diff --git a/app/build.gradle b/app/build.gradle index 152d37b1..bf82e5d5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,7 +1,6 @@ plugins { id 'com.android.application' id 'kotlin-android' - id 'kotlin-android-extensions' id 'org.jetbrains.kotlin.plugin.serialization' version "$kotlin_version" } @@ -12,12 +11,13 @@ if (keystorePropertiesFile.exists()) { } android { - compileSdk 33 + namespace "com.simplemobiletools.dialer" + compileSdk 34 defaultConfig { applicationId "com.simplemobiletools.dialer" - minSdkVersion 23 - targetSdkVersion 33 + minSdk 23 + targetSdk 34 versionCode 56 versionName "5.18.0" setProperty("archivesBaseName", "dialer") @@ -34,6 +34,11 @@ android { } } + buildFeatures { + buildConfig true + viewBinding true + } + buildTypes { debug { applicationIdSuffix ".debug" @@ -47,6 +52,15 @@ android { } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + kotlinOptions { + jvmTarget = '17' + } + flavorDimensions = ["variants"] productFlavors { core {} @@ -65,7 +79,7 @@ android { } dependencies { - implementation 'com.github.SimpleMobileTools:Simple-Commons:91763fe00f' + implementation 'com.github.SimpleMobileTools:Simple-Commons:565200547d' implementation 'com.github.tibbi:IndicatorFastScroll:4524cd0b61' implementation 'me.grantland:autofittextview:0.2.1' implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1" diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/activities/CallActivity.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/activities/CallActivity.kt index b172dd5c..7331de0f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/activities/CallActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/activities/CallActivity.kt @@ -26,13 +26,12 @@ import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.models.SimpleListItem import com.simplemobiletools.dialer.R +import com.simplemobiletools.dialer.databinding.ActivityCallBinding import com.simplemobiletools.dialer.dialogs.DynamicBottomSheetChooserDialog import com.simplemobiletools.dialer.extensions.* import com.simplemobiletools.dialer.helpers.* import com.simplemobiletools.dialer.models.AudioRoute import com.simplemobiletools.dialer.models.CallContact -import kotlinx.android.synthetic.main.activity_call.* -import kotlinx.android.synthetic.main.dialpad.* import kotlin.math.max import kotlin.math.min @@ -45,6 +44,8 @@ class CallActivity : SimpleActivity() { } } + private val binding by viewBinding(ActivityCallBinding::inflate) + private var isSpeakerOn = false private var isMicrophoneOff = false private var isCallEnded = false @@ -63,14 +64,14 @@ class CallActivity : SimpleActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_call) + setContentView(binding.root) if (CallManager.getPhoneState() == NoCall) { finish() return } - updateTextColors(call_holder) + updateTextColors(binding.callHolder) initButtons() audioManager.mode = AudioManager.MODE_IN_CALL addLockScreenFlags() @@ -104,7 +105,7 @@ class CallActivity : SimpleActivity() { } override fun onBackPressed() { - if (dialpad_wrapper.isVisible()) { + if (binding.dialpadWrapper.isVisible()) { hideDialpad() return } else { @@ -117,119 +118,121 @@ class CallActivity : SimpleActivity() { } } - private fun initButtons() { + private fun initButtons() = binding.apply { if (config.disableSwipeToAnswer) { - call_draggable.beGone() - call_draggable_background.beGone() - call_left_arrow.beGone() - call_right_arrow.beGone() + callDraggable.beGone() + callDraggableBackground.beGone() + callLeftArrow.beGone() + callRightArrow.beGone() - call_decline.setOnClickListener { + callDecline.setOnClickListener { endCall() } - call_accept.setOnClickListener { + callAccept.setOnClickListener { acceptCall() } } else { handleSwipe() } - call_toggle_microphone.setOnClickListener { + callToggleMicrophone.setOnClickListener { toggleMicrophone() } - call_toggle_speaker.setOnClickListener { + callToggleSpeaker.setOnClickListener { changeCallAudioRoute() } - call_dialpad.setOnClickListener { + callDialpad.setOnClickListener { toggleDialpadVisibility() } - dialpad_close.setOnClickListener { + dialpadClose.setOnClickListener { hideDialpad() } - call_toggle_hold.setOnClickListener { + callToggleHold.setOnClickListener { toggleHold() } - call_add.setOnClickListener { + callAdd.setOnClickListener { Intent(applicationContext, DialpadActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY) startActivity(this) } } - call_swap.setOnClickListener { + callSwap.setOnClickListener { CallManager.swap() } - call_merge.setOnClickListener { + callMerge.setOnClickListener { CallManager.merge() } - call_manage.setOnClickListener { - startActivity(Intent(this, ConferenceActivity::class.java)) + callManage.setOnClickListener { + startActivity(Intent(this@CallActivity, ConferenceActivity::class.java)) } - call_end.setOnClickListener { + callEnd.setOnClickListener { endCall() } - dialpad_0_holder.setOnClickListener { dialpadPressed('0') } - dialpad_1_holder.setOnClickListener { dialpadPressed('1') } - dialpad_2_holder.setOnClickListener { dialpadPressed('2') } - dialpad_3_holder.setOnClickListener { dialpadPressed('3') } - dialpad_4_holder.setOnClickListener { dialpadPressed('4') } - dialpad_5_holder.setOnClickListener { dialpadPressed('5') } - dialpad_6_holder.setOnClickListener { dialpadPressed('6') } - dialpad_7_holder.setOnClickListener { dialpadPressed('7') } - dialpad_8_holder.setOnClickListener { dialpadPressed('8') } - dialpad_9_holder.setOnClickListener { dialpadPressed('9') } + dialpadInclude.apply { + dialpad0Holder.setOnClickListener { dialpadPressed('0') } + dialpad1Holder.setOnClickListener { dialpadPressed('1') } + dialpad2Holder.setOnClickListener { dialpadPressed('2') } + dialpad3Holder.setOnClickListener { dialpadPressed('3') } + dialpad4Holder.setOnClickListener { dialpadPressed('4') } + dialpad5Holder.setOnClickListener { dialpadPressed('5') } + dialpad6Holder.setOnClickListener { dialpadPressed('6') } + dialpad7Holder.setOnClickListener { dialpadPressed('7') } + dialpad8Holder.setOnClickListener { dialpadPressed('8') } + dialpad9Holder.setOnClickListener { dialpadPressed('9') } - arrayOf( - dialpad_0_holder, - dialpad_1_holder, - dialpad_2_holder, - dialpad_3_holder, - dialpad_4_holder, - dialpad_5_holder, - dialpad_6_holder, - dialpad_7_holder, - dialpad_8_holder, - dialpad_9_holder, - dialpad_plus_holder, - dialpad_asterisk_holder, - dialpad_hashtag_holder - ).forEach { - it.background = ResourcesCompat.getDrawable(resources, R.drawable.pill_background, theme) - it.background?.alpha = LOWER_ALPHA_INT + arrayOf( + dialpad0Holder, + dialpad1Holder, + dialpad2Holder, + dialpad3Holder, + dialpad4Holder, + dialpad5Holder, + dialpad6Holder, + dialpad7Holder, + dialpad8Holder, + dialpad9Holder, + dialpadPlusHolder, + dialpadAsteriskHolder, + dialpadHashtagHolder + ).forEach { + it.background = ResourcesCompat.getDrawable(resources, R.drawable.pill_background, theme) + it.background?.alpha = LOWER_ALPHA_INT + } + + dialpad0Holder.setOnLongClickListener { dialpadPressed('+'); true } + dialpadAsteriskHolder.setOnClickListener { dialpadPressed('*') } + dialpadHashtagHolder.setOnClickListener { dialpadPressed('#') } } - dialpad_0_holder.setOnLongClickListener { dialpadPressed('+'); true } - dialpad_asterisk_holder.setOnClickListener { dialpadPressed('*') } - dialpad_hashtag_holder.setOnClickListener { dialpadPressed('#') } - - dialpad_wrapper.setBackgroundColor(getProperBackgroundColor()) - arrayOf(dialpad_close, call_sim_image).forEach { + dialpadWrapper.setBackgroundColor(getProperBackgroundColor()) + arrayOf(dialpadClose, callSimImage).forEach { it.applyColorFilter(getProperTextColor()) } val bgColor = getProperBackgroundColor() val inactiveColor = getInactiveButtonColor() arrayOf( - call_toggle_microphone, call_toggle_speaker, call_dialpad, - call_toggle_hold, call_add, call_swap, call_merge, call_manage + callToggleMicrophone, callToggleSpeaker, callDialpad, + callToggleHold, callAdd, callSwap, callMerge, callManage ).forEach { it.applyColorFilter(bgColor.getContrastColor()) it.background.applyColorFilter(inactiveColor) } arrayOf( - call_toggle_microphone, call_toggle_speaker, call_dialpad, - call_toggle_hold, call_add, call_swap, call_merge, call_manage + callToggleMicrophone, callToggleSpeaker, callDialpad, + callToggleHold, callAdd, callSwap, callMerge, callManage ).forEach { imageView -> imageView.setOnLongClickListener { if (!imageView.contentDescription.isNullOrEmpty()) { @@ -239,16 +242,16 @@ class CallActivity : SimpleActivity() { } } - call_sim_id.setTextColor(getProperTextColor().getContrastColor()) - dialpad_input.disableKeyboard() + callSimId.setTextColor(getProperTextColor().getContrastColor()) + dialpadInput.disableKeyboard() - dialpad_wrapper.onGlobalLayout { - dialpadHeight = dialpad_wrapper.height.toFloat() + dialpadWrapper.onGlobalLayout { + dialpadHeight = dialpadWrapper.height.toFloat() } } @SuppressLint("ClickableViewAccessibility") - private fun handleSwipe() { + private fun handleSwipe() = binding.apply { var minDragX = 0f var maxDragX = 0f var initialDraggableX = 0f @@ -262,84 +265,85 @@ class CallActivity : SimpleActivity() { var rightArrowTranslation = 0f val isRtl = isRTLLayout - call_accept.onGlobalLayout { + callAccept.onGlobalLayout { minDragX = if (isRtl) { - call_accept.left.toFloat() + callAccept.left.toFloat() } else { - call_decline.left.toFloat() + callDecline.left.toFloat() } maxDragX = if (isRtl) { - call_decline.left.toFloat() + callDecline.left.toFloat() } else { - call_accept.left.toFloat() + callAccept.left.toFloat() } - initialDraggableX = call_draggable.left.toFloat() - initialLeftArrowX = call_left_arrow.x - initialRightArrowX = call_right_arrow.x - initialLeftArrowScaleX = call_left_arrow.scaleX - initialLeftArrowScaleY = call_left_arrow.scaleY - initialRightArrowScaleX = call_right_arrow.scaleX - initialRightArrowScaleY = call_right_arrow.scaleY + initialDraggableX = callDraggable.left.toFloat() + initialLeftArrowX = callLeftArrow.x + initialRightArrowX = callRightArrow.x + initialLeftArrowScaleX = callLeftArrow.scaleX + initialLeftArrowScaleY = callLeftArrow.scaleY + initialRightArrowScaleX = callRightArrow.scaleX + initialRightArrowScaleY = callRightArrow.scaleY leftArrowTranslation = if (isRtl) { - call_accept.x + callAccept.x } else { - -call_decline.x + -callDecline.x } rightArrowTranslation = if (isRtl) { - -call_accept.x + -callAccept.x } else { - call_decline.x + callDecline.x } if (isRtl) { - call_left_arrow.setImageResource(R.drawable.ic_chevron_right_vector) - call_right_arrow.setImageResource(R.drawable.ic_chevron_left_vector) + callLeftArrow.setImageResource(R.drawable.ic_chevron_right_vector) + callRightArrow.setImageResource(R.drawable.ic_chevron_left_vector) } - call_left_arrow.applyColorFilter(getColor(R.color.md_red_400)) - call_right_arrow.applyColorFilter(getColor(R.color.md_green_400)) + callLeftArrow.applyColorFilter(getColor(R.color.md_red_400)) + callRightArrow.applyColorFilter(getColor(R.color.md_green_400)) - startArrowAnimation(call_left_arrow, initialLeftArrowX, initialLeftArrowScaleX, initialLeftArrowScaleY, leftArrowTranslation) - startArrowAnimation(call_right_arrow, initialRightArrowX, initialRightArrowScaleX, initialRightArrowScaleY, rightArrowTranslation) + startArrowAnimation(callLeftArrow, initialLeftArrowX, initialLeftArrowScaleX, initialLeftArrowScaleY, leftArrowTranslation) + startArrowAnimation(callRightArrow, initialRightArrowX, initialRightArrowScaleX, initialRightArrowScaleY, rightArrowTranslation) } - call_draggable.drawable.mutate().setTint(getProperTextColor()) - call_draggable_background.drawable.mutate().setTint(getProperTextColor()) + callDraggable.drawable.mutate().setTint(getProperTextColor()) + callDraggableBackground.drawable.mutate().setTint(getProperTextColor()) var lock = false - call_draggable.setOnTouchListener { _, event -> + callDraggable.setOnTouchListener { _, event -> when (event.action) { MotionEvent.ACTION_DOWN -> { dragDownX = event.x - call_draggable_background.animate().alpha(0f) + callDraggableBackground.animate().alpha(0f) stopAnimation = true - call_left_arrow.animate().alpha(0f) - call_right_arrow.animate().alpha(0f) + callLeftArrow.animate().alpha(0f) + callRightArrow.animate().alpha(0f) lock = false } + MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { dragDownX = 0f - call_draggable.animate().x(initialDraggableX).withEndAction { - call_draggable_background.animate().alpha(0.2f) + callDraggable.animate().x(initialDraggableX).withEndAction { + callDraggableBackground.animate().alpha(0.2f) } - call_draggable.setImageDrawable(getDrawable(R.drawable.ic_phone_down_vector)) - call_draggable.drawable.mutate().setTint(getProperTextColor()) - call_left_arrow.animate().alpha(1f) - call_right_arrow.animate().alpha(1f) + callDraggable.setImageDrawable(getDrawable(R.drawable.ic_phone_down_vector)) + callDraggable.drawable.mutate().setTint(getProperTextColor()) + callLeftArrow.animate().alpha(1f) + callRightArrow.animate().alpha(1f) stopAnimation = false - startArrowAnimation(call_left_arrow, initialLeftArrowX, initialLeftArrowScaleX, initialLeftArrowScaleY, leftArrowTranslation) - startArrowAnimation(call_right_arrow, initialRightArrowX, initialRightArrowScaleX, initialRightArrowScaleY, rightArrowTranslation) + startArrowAnimation(callLeftArrow, initialLeftArrowX, initialLeftArrowScaleX, initialLeftArrowScaleY, leftArrowTranslation) + startArrowAnimation(callRightArrow, initialRightArrowX, initialRightArrowScaleX, initialRightArrowScaleY, rightArrowTranslation) } MotionEvent.ACTION_MOVE -> { - call_draggable.x = min(maxDragX, max(minDragX, event.rawX - dragDownX)) + callDraggable.x = min(maxDragX, max(minDragX, event.rawX - dragDownX)) when { - call_draggable.x >= maxDragX - 50f -> { + callDraggable.x >= maxDragX - 50f -> { if (!lock) { lock = true - call_draggable.performHapticFeedback() + callDraggable.performHapticFeedback() if (isRtl) { endCall() } else { @@ -347,10 +351,11 @@ class CallActivity : SimpleActivity() { } } } - call_draggable.x <= minDragX + 50f -> { + + callDraggable.x <= minDragX + 50f -> { if (!lock) { lock = true - call_draggable.performHapticFeedback() + callDraggable.performHapticFeedback() if (isRtl) { acceptCall() } else { @@ -358,23 +363,25 @@ class CallActivity : SimpleActivity() { } } } - call_draggable.x > initialDraggableX -> { + + callDraggable.x > initialDraggableX -> { lock = false val drawableRes = if (isRtl) { R.drawable.ic_phone_down_red_vector } else { R.drawable.ic_phone_green_vector } - call_draggable.setImageDrawable(getDrawable(drawableRes)) + callDraggable.setImageDrawable(getDrawable(drawableRes)) } - call_draggable.x <= initialDraggableX -> { + + callDraggable.x <= initialDraggableX -> { lock = false val drawableRes = if (isRtl) { R.drawable.ic_phone_green_vector } else { R.drawable.ic_phone_down_red_vector } - call_draggable.setImageDrawable(getDrawable(drawableRes)) + callDraggable.setImageDrawable(getDrawable(drawableRes)) } } } @@ -405,7 +412,7 @@ class CallActivity : SimpleActivity() { private fun dialpadPressed(char: Char) { CallManager.keypad(char) - dialpad_input.addCharacter(char) + binding.dialpadInput.addCharacter(char) } private fun changeCallAudioRoute() { @@ -449,7 +456,7 @@ class CallActivity : SimpleActivity() { isSpeakerOn = route == AudioRoute.SPEAKER val supportedAudioRoutes = CallManager.getSupportedAudioRoutes() - call_toggle_speaker.apply { + binding.callToggleSpeaker.apply { val bluetoothConnected = supportedAudioRoutes.contains(AudioRoute.BLUETOOTH) contentDescription = if (bluetoothConnected) { getString(R.string.choose_audio_route) @@ -463,7 +470,7 @@ class CallActivity : SimpleActivity() { setImageResource(route.iconRes) } } - toggleButtonColor(call_toggle_speaker, enabled = route != AudioRoute.EARPIECE && route != AudioRoute.WIRED_HEADSET) + toggleButtonColor(binding.callToggleSpeaker, enabled = route != AudioRoute.EARPIECE && route != AudioRoute.WIRED_HEADSET) createOrUpdateAudioRouteChooser(supportedAudioRoutes, create = false) if (isSpeakerOn) { @@ -482,20 +489,20 @@ class CallActivity : SimpleActivity() { } private fun updateMicrophoneButton() { - toggleButtonColor(call_toggle_microphone, isMicrophoneOff) - call_toggle_microphone.contentDescription = getString(if (isMicrophoneOff) R.string.turn_microphone_on else R.string.turn_microphone_off) + toggleButtonColor(binding.callToggleMicrophone, isMicrophoneOff) + binding.callToggleMicrophone.contentDescription = getString(if (isMicrophoneOff) R.string.turn_microphone_on else R.string.turn_microphone_off) } private fun toggleDialpadVisibility() { - if (dialpad_wrapper.isVisible()) hideDialpad() else showDialpad() + if (binding.dialpadWrapper.isVisible()) hideDialpad() else showDialpad() } private fun findVisibleViewsUnderDialpad(): Sequence> { - return ongoing_call_holder.children.filter { it.isVisible() }.map { view -> Pair(view, view.alpha) } + return binding.ongoingCallHolder.children.filter { it.isVisible() }.map { view -> Pair(view, view.alpha) } } private fun showDialpad() { - dialpad_wrapper.apply { + binding.dialpadWrapper.apply { translationY = dialpadHeight alpha = 0f animate() @@ -518,8 +525,8 @@ class CallActivity : SimpleActivity() { } private fun hideDialpad() { - dialpad_wrapper.animate() - .withEndAction { dialpad_wrapper.beGone() } + binding.dialpadWrapper.animate() + .withEndAction { binding.dialpadWrapper.beGone() } .setInterpolator(AccelerateDecelerateInterpolator()) .setDuration(200L) .alpha(0f) @@ -536,9 +543,9 @@ class CallActivity : SimpleActivity() { private fun toggleHold() { val isOnHold = CallManager.toggleHold() - toggleButtonColor(call_toggle_hold, isOnHold) - call_toggle_hold.contentDescription = getString(if (isOnHold) R.string.resume_call else R.string.hold_call) - hold_status_label.beVisibleIf(isOnHold) + toggleButtonColor(binding.callToggleHold, isOnHold) + binding.callToggleHold.contentDescription = getString(if (isOnHold) R.string.resume_call else R.string.hold_call) + binding.holdStatusLabel.beVisibleIf(isOnHold) } private fun updateOtherPersonsInfo(avatar: Bitmap?) { @@ -546,21 +553,23 @@ class CallActivity : SimpleActivity() { return } - caller_name_label.text = if (callContact!!.name.isNotEmpty()) callContact!!.name else getString(R.string.unknown_caller) - if (callContact!!.number.isNotEmpty() && callContact!!.number != callContact!!.name) { - caller_number.text = callContact!!.number + binding.apply { + callerNameLabel.text = if (callContact!!.name.isNotEmpty()) callContact!!.name else getString(R.string.unknown_caller) + if (callContact!!.number.isNotEmpty() && callContact!!.number != callContact!!.name) { + callerNumber.text = callContact!!.number - if (callContact!!.numberLabel.isNotEmpty()) { - caller_number.text = "${callContact!!.number} - ${callContact!!.numberLabel}" + if (callContact!!.numberLabel.isNotEmpty()) { + callerNumber.text = "${callContact!!.number} - ${callContact!!.numberLabel}" + } + } else { + callerNumber.beGone() } - } else { - caller_number.beGone() - } - if (avatar != null) { - caller_avatar.setImageBitmap(avatar) - } else { - caller_avatar.setImageDrawable(null) + if (avatar != null) { + callerAvatar.setImageBitmap(avatar) + } else { + callerAvatar.setImageDrawable(null) + } } } @@ -579,9 +588,11 @@ class CallActivity : SimpleActivity() { if (accounts.size > 1) { accounts.forEachIndexed { index, account -> if (account == CallManager.getPrimaryCall()?.details?.accountHandle) { - call_sim_id.text = "${index + 1}" - call_sim_id.beVisible() - call_sim_image.beVisible() + binding.apply { + callSimId.text = "${index + 1}" + callSimId.beVisible() + callSimImage.beVisible() + } val acceptDrawableId = when (index) { 0 -> R.drawable.ic_phone_one_vector @@ -592,7 +603,7 @@ class CallActivity : SimpleActivity() { val rippleBg = resources.getDrawable(R.drawable.ic_call_accept, theme) as RippleDrawable val layerDrawable = rippleBg.findDrawableByLayerId(R.id.accept_call_background_holder) as LayerDrawable layerDrawable.setDrawableByLayerId(R.id.accept_call_icon, getDrawable(acceptDrawableId)) - call_accept.setImageDrawable(rippleBg) + binding.callAccept.setImageDrawable(rippleBg) } } } @@ -616,13 +627,15 @@ class CallActivity : SimpleActivity() { else -> 0 } - if (statusTextId != 0) { - call_status_label.text = getString(statusTextId) - } + binding.apply { + if (statusTextId != 0) { + callStatusLabel.text = getString(statusTextId) + } - call_manage.beVisibleIf(call.hasCapability(Call.Details.CAPABILITY_MANAGE_CONFERENCE)) - setActionButtonEnabled(call_swap, state == Call.STATE_ACTIVE) - setActionButtonEnabled(call_merge, state == Call.STATE_ACTIVE) + callManage.beVisibleIf(call.hasCapability(Call.Details.CAPABILITY_MANAGE_CONFERENCE)) + setActionButtonEnabled(callSwap, state == Call.STATE_ACTIVE) + setActionButtonEnabled(callMerge, state == Call.STATE_ACTIVE) + } } private fun updateState() { @@ -633,8 +646,8 @@ class CallActivity : SimpleActivity() { val state = phoneState.call.getStateCompat() val isSingleCallActionsEnabled = (state == Call.STATE_ACTIVE || state == Call.STATE_DISCONNECTED || state == Call.STATE_DISCONNECTING || state == Call.STATE_HOLDING) - setActionButtonEnabled(call_toggle_hold, isSingleCallActionsEnabled) - setActionButtonEnabled(call_add, isSingleCallActionsEnabled) + setActionButtonEnabled(binding.callToggleHold, isSingleCallActionsEnabled) + setActionButtonEnabled(binding.callAdd, isSingleCallActionsEnabled) } else if (phoneState is TwoCalls) { updateCallState(phoneState.active) updateCallOnHoldState(phoneState.onHold) @@ -648,13 +661,15 @@ class CallActivity : SimpleActivity() { if (hasCallOnHold) { getCallContact(applicationContext, call) { contact -> runOnUiThread { - on_hold_caller_name.text = getContactNameOrNumber(contact) + binding.onHoldCallerName.text = getContactNameOrNumber(contact) } } } - on_hold_status_holder.beVisibleIf(hasCallOnHold) - controls_single_call.beVisibleIf(!hasCallOnHold) - controls_two_calls.beVisibleIf(hasCallOnHold) + binding.apply { + onHoldStatusHolder.beVisibleIf(hasCallOnHold) + controlsSingleCall.beVisibleIf(!hasCallOnHold) + controlsTwoCalls.beVisibleIf(hasCallOnHold) + } } private fun updateCallContactInfo(call: Call?) { @@ -677,18 +692,18 @@ class CallActivity : SimpleActivity() { private fun initOutgoingCallUI() { enableProximitySensor() - incoming_call_holder.beGone() - ongoing_call_holder.beVisible() + binding.incomingCallHolder.beGone() + binding.ongoingCallHolder.beVisible() } private fun callRinging() { - incoming_call_holder.beVisible() + binding.incomingCallHolder.beVisible() } private fun callStarted() { enableProximitySensor() - incoming_call_holder.beGone() - ongoing_call_holder.beVisible() + binding.incomingCallHolder.beGone() + binding.ongoingCallHolder.beVisible() callDurationHandler.removeCallbacks(updateCallDurationTask) callDurationHandler.post(updateCallDurationTask) } @@ -719,13 +734,13 @@ class CallActivity : SimpleActivity() { isCallEnded = true if (callDuration > 0) { runOnUiThread { - call_status_label.text = "${callDuration.getFormattedDuration()} (${getString(R.string.call_ended)})" + binding.callStatusLabel.text = "${callDuration.getFormattedDuration()} (${getString(R.string.call_ended)})" Handler().postDelayed({ finishAndRemoveTask() }, 3000) } } else { - call_status_label.text = getString(R.string.call_ended) + binding.callStatusLabel.text = getString(R.string.call_ended) finish() } } @@ -750,7 +765,7 @@ class CallActivity : SimpleActivity() { override fun run() { callDuration = CallManager.getPrimaryCall().getCallDuration() if (!isCallEnded) { - call_status_label.text = callDuration.getFormattedDuration() + binding.callStatusLabel.text = callDuration.getFormattedDuration() callDurationHandler.postDelayed(this, 1000) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/activities/ConferenceActivity.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/activities/ConferenceActivity.kt index a4da2049..4de8a155 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/activities/ConferenceActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/activities/ConferenceActivity.kt @@ -1,25 +1,28 @@ package com.simplemobiletools.dialer.activities import android.os.Bundle +import com.simplemobiletools.commons.extensions.viewBinding import com.simplemobiletools.commons.helpers.NavigationIcon -import com.simplemobiletools.dialer.R import com.simplemobiletools.dialer.adapters.ConferenceCallsAdapter +import com.simplemobiletools.dialer.databinding.ActivityConferenceBinding import com.simplemobiletools.dialer.helpers.CallManager -import kotlinx.android.synthetic.main.activity_conference.* class ConferenceActivity : SimpleActivity() { + private val binding by viewBinding(ActivityConferenceBinding::inflate) override fun onCreate(savedInstanceState: Bundle?) { isMaterialActivity = true super.onCreate(savedInstanceState) - setContentView(R.layout.activity_conference) - updateMaterialActivityViews(conference_coordinator, conference_list, useTransparentNavigation = true, useTopSearchMenu = false) - setupMaterialScrollListener(conference_list, conference_toolbar) - conference_list.adapter = ConferenceCallsAdapter(this, conference_list, ArrayList(CallManager.getConferenceCalls())) {} + setContentView(binding.root) + binding.apply { + updateMaterialActivityViews(conferenceCoordinator, conferenceList, useTransparentNavigation = true, useTopSearchMenu = false) + setupMaterialScrollListener(conferenceList, conferenceToolbar) + conferenceList.adapter = ConferenceCallsAdapter(this@ConferenceActivity, conferenceList, ArrayList(CallManager.getConferenceCalls())) {} + } } override fun onResume() { super.onResume() - setupToolbar(conference_toolbar, NavigationIcon.Arrow) + setupToolbar(binding.conferenceToolbar, NavigationIcon.Arrow) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/activities/DialpadActivity.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/activities/DialpadActivity.kt index 3ee302ae..f18bf27b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/activities/DialpadActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/activities/DialpadActivity.kt @@ -26,17 +26,17 @@ import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.models.contacts.Contact import com.simplemobiletools.dialer.R import com.simplemobiletools.dialer.adapters.ContactsAdapter +import com.simplemobiletools.dialer.databinding.ActivityDialpadBinding import com.simplemobiletools.dialer.extensions.* import com.simplemobiletools.dialer.helpers.DIALPAD_TONE_LENGTH_MS import com.simplemobiletools.dialer.helpers.ToneGeneratorHelper import com.simplemobiletools.dialer.models.SpeedDial -import kotlinx.android.synthetic.main.activity_dialpad.* -import kotlinx.android.synthetic.main.activity_dialpad.dialpad_holder -import kotlinx.android.synthetic.main.dialpad.* import java.util.* import kotlin.math.roundToInt class DialpadActivity : SimpleActivity() { + private val binding by viewBinding(ActivityDialpadBinding::inflate) + private var allContacts = ArrayList() private var speedDialValues = ArrayList() private val russianCharsMap = HashMap() @@ -49,48 +49,53 @@ class DialpadActivity : SimpleActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_dialpad) + setContentView(binding.root) hasRussianLocale = Locale.getDefault().language == "ru" - updateMaterialActivityViews(dialpad_coordinator, dialpad_holder, useTransparentNavigation = true, useTopSearchMenu = false) - setupMaterialScrollListener(dialpad_list, dialpad_toolbar) + binding.apply { + updateMaterialActivityViews(dialpadCoordinator, dialpadHolder, useTransparentNavigation = true, useTopSearchMenu = false) + setupMaterialScrollListener(dialpadList, dialpadToolbar) + } + updateNavigationBarColor(getProperBackgroundColor()) if (checkAppSideloading()) { return } - if (config.hideDialpadNumbers) { - dialpad_1_holder.isVisible = false - dialpad_2_holder.isVisible = false - dialpad_3_holder.isVisible = false - dialpad_4_holder.isVisible = false - dialpad_5_holder.isVisible = false - dialpad_6_holder.isVisible = false - dialpad_7_holder.isVisible = false - dialpad_8_holder.isVisible = false - dialpad_9_holder.isVisible = false - dialpad_plus_holder.isVisible = true - dialpad_0_holder.visibility = View.INVISIBLE - } + binding.dialpadWrapper.apply { + if (config.hideDialpadNumbers) { + dialpad1Holder.isVisible = false + dialpad2Holder.isVisible = false + dialpad3Holder.isVisible = false + dialpad4Holder.isVisible = false + dialpad5Holder.isVisible = false + dialpad6Holder.isVisible = false + dialpad7Holder.isVisible = false + dialpad8Holder.isVisible = false + dialpad9Holder.isVisible = false + dialpadPlusHolder.isVisible = true + dialpad0Holder.visibility = View.INVISIBLE + } - arrayOf( - dialpad_0_holder, - dialpad_1_holder, - dialpad_2_holder, - dialpad_3_holder, - dialpad_4_holder, - dialpad_5_holder, - dialpad_6_holder, - dialpad_7_holder, - dialpad_8_holder, - dialpad_9_holder, - dialpad_plus_holder, - dialpad_asterisk_holder, - dialpad_hashtag_holder - ).forEach { - it.background = ResourcesCompat.getDrawable(resources, R.drawable.pill_background, theme) - it.background?.alpha = LOWER_ALPHA_INT + arrayOf( + dialpad0Holder, + dialpad1Holder, + dialpad2Holder, + dialpad3Holder, + dialpad4Holder, + dialpad5Holder, + dialpad6Holder, + dialpad7Holder, + dialpad8Holder, + dialpad9Holder, + dialpadPlusHolder, + dialpadAsteriskHolder, + dialpadHashtagHolder + ).forEach { + it.background = ResourcesCompat.getDrawable(resources, R.drawable.pill_background, theme) + it.background?.alpha = LOWER_ALPHA_INT + } } setupOptionsMenu() @@ -99,46 +104,50 @@ class DialpadActivity : SimpleActivity() { toneGeneratorHelper = ToneGeneratorHelper(this, DIALPAD_TONE_LENGTH_MS) - if (hasRussianLocale) { - initRussianChars() - dialpad_2_letters.append("\nАБВГ") - dialpad_3_letters.append("\nДЕЁЖЗ") - dialpad_4_letters.append("\nИЙКЛ") - dialpad_5_letters.append("\nМНОП") - dialpad_6_letters.append("\nРСТУ") - dialpad_7_letters.append("\nФХЦЧ") - dialpad_8_letters.append("\nШЩЪЫ") - dialpad_9_letters.append("\nЬЭЮЯ") + binding.dialpadWrapper.apply { + if (hasRussianLocale) { + initRussianChars() + dialpad2Letters.append("\nАБВГ") + dialpad3Letters.append("\nДЕЁЖЗ") + dialpad4Letters.append("\nИЙКЛ") + dialpad5Letters.append("\nМНОП") + dialpad6Letters.append("\nРСТУ") + dialpad7Letters.append("\nФХЦЧ") + dialpad8Letters.append("\nШЩЪЫ") + dialpad9Letters.append("\nЬЭЮЯ") - val fontSize = resources.getDimension(R.dimen.small_text_size) - arrayOf( - dialpad_2_letters, dialpad_3_letters, dialpad_4_letters, dialpad_5_letters, dialpad_6_letters, dialpad_7_letters, dialpad_8_letters, - dialpad_9_letters - ).forEach { - it.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize) + val fontSize = resources.getDimension(R.dimen.small_text_size) + arrayOf( + dialpad2Letters, dialpad3Letters, dialpad4Letters, dialpad5Letters, dialpad6Letters, dialpad7Letters, dialpad8Letters, + dialpad9Letters + ).forEach { + it.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize) + } } + + setupCharClick(dialpad1Holder, '1') + setupCharClick(dialpad2Holder, '2') + setupCharClick(dialpad3Holder, '3') + setupCharClick(dialpad4Holder, '4') + setupCharClick(dialpad5Holder, '5') + setupCharClick(dialpad6Holder, '6') + setupCharClick(dialpad7Holder, '7') + setupCharClick(dialpad8Holder, '8') + setupCharClick(dialpad9Holder, '9') + setupCharClick(dialpad0Holder, '0') + setupCharClick(dialpadPlusHolder, '+', longClickable = false) + setupCharClick(dialpadAsteriskHolder, '*', longClickable = false) + setupCharClick(dialpadHashtagHolder, '#', longClickable = false) } - setupCharClick(dialpad_1_holder, '1') - setupCharClick(dialpad_2_holder, '2') - setupCharClick(dialpad_3_holder, '3') - setupCharClick(dialpad_4_holder, '4') - setupCharClick(dialpad_5_holder, '5') - setupCharClick(dialpad_6_holder, '6') - setupCharClick(dialpad_7_holder, '7') - setupCharClick(dialpad_8_holder, '8') - setupCharClick(dialpad_9_holder, '9') - setupCharClick(dialpad_0_holder, '0') - setupCharClick(dialpad_plus_holder, '+', longClickable = false) - setupCharClick(dialpad_asterisk_holder, '*', longClickable = false) - setupCharClick(dialpad_hashtag_holder, '#', longClickable = false) - - dialpad_clear_char.setOnClickListener { clearChar(it) } - dialpad_clear_char.setOnLongClickListener { clearInput(); true } - dialpad_call_button.setOnClickListener { initCall(dialpad_input.value, 0) } - dialpad_input.onTextChangeListener { dialpadValueChanged(it) } - dialpad_input.requestFocus() - dialpad_input.disableKeyboard() + binding.apply { + dialpadClearChar.setOnClickListener { clearChar(it) } + dialpadClearChar.setOnLongClickListener { clearInput(); true } + dialpadCallButton.setOnClickListener { initCall(dialpadInput.value, 0) } + dialpadInput.onTextChangeListener { dialpadValueChanged(it) } + dialpadInput.requestFocus() + dialpadInput.disableKeyboard() + } ContactsHelper(this).getContacts(showOnlyContactsWithNumbers = true) { allContacts -> gotContacts(allContacts) @@ -147,11 +156,13 @@ class DialpadActivity : SimpleActivity() { val properPrimaryColor = getProperPrimaryColor() val callIconId = if (areMultipleSIMsAvailable()) { val callIcon = resources.getColoredDrawableWithColor(R.drawable.ic_phone_two_vector, properPrimaryColor.getContrastColor()) - dialpad_call_two_button.setImageDrawable(callIcon) - dialpad_call_two_button.background.applyColorFilter(properPrimaryColor) - dialpad_call_two_button.beVisible() - dialpad_call_two_button.setOnClickListener { - initCall(dialpad_input.value, 1) + binding.apply { + dialpadCallTwoButton.setImageDrawable(callIcon) + dialpadCallTwoButton.background.applyColorFilter(properPrimaryColor) + dialpadCallTwoButton.beVisible() + dialpadCallTwoButton.setOnClickListener { + initCall(dialpadInput.value, 1) + } } R.drawable.ic_phone_one_vector @@ -159,27 +170,29 @@ class DialpadActivity : SimpleActivity() { R.drawable.ic_phone_vector } - val callIcon = resources.getColoredDrawableWithColor(callIconId, properPrimaryColor.getContrastColor()) - dialpad_call_button.setImageDrawable(callIcon) - dialpad_call_button.background.applyColorFilter(properPrimaryColor) + binding.apply { + val callIcon = resources.getColoredDrawableWithColor(callIconId, properPrimaryColor.getContrastColor()) + dialpadCallButton.setImageDrawable(callIcon) + dialpadCallButton.background.applyColorFilter(properPrimaryColor) - letter_fastscroller.textColor = getProperTextColor().getColorStateList() - letter_fastscroller.pressedTextColor = properPrimaryColor - letter_fastscroller_thumb.setupWithFastScroller(letter_fastscroller) - letter_fastscroller_thumb.textColor = properPrimaryColor.getContrastColor() - letter_fastscroller_thumb.thumbColor = properPrimaryColor.getColorStateList() + letterFastscroller.textColor = getProperTextColor().getColorStateList() + letterFastscroller.pressedTextColor = properPrimaryColor + letterFastscrollerThumb.setupWithFastScroller(letterFastscroller) + letterFastscrollerThumb.textColor = properPrimaryColor.getContrastColor() + letterFastscrollerThumb.thumbColor = properPrimaryColor.getColorStateList() + } } override fun onResume() { super.onResume() - updateTextColors(dialpad_holder) - dialpad_clear_char.applyColorFilter(getProperTextColor()) + updateTextColors(binding.dialpadHolder) + binding.dialpadClearChar.applyColorFilter(getProperTextColor()) updateNavigationBarColor(getProperBackgroundColor()) - setupToolbar(dialpad_toolbar, NavigationIcon.Arrow) + setupToolbar(binding.dialpadToolbar, NavigationIcon.Arrow) } private fun setupOptionsMenu() { - dialpad_toolbar.setOnMenuItemClickListener { menuItem -> + binding.dialpadToolbar.setOnMenuItemClickListener { menuItem -> when (menuItem.itemId) { R.id.add_number_to_contact -> addNumberToContact() else -> return@setOnMenuItemClickListener false @@ -191,8 +204,8 @@ class DialpadActivity : SimpleActivity() { private fun checkDialIntent(): Boolean { return if ((intent.action == Intent.ACTION_DIAL || intent.action == Intent.ACTION_VIEW) && intent.data != null && intent.dataString?.contains("tel:") == true) { val number = Uri.decode(intent.dataString).substringAfter("tel:") - dialpad_input.setText(number) - dialpad_input.setSelection(number.length) + binding.dialpadInput.setText(number) + binding.dialpadInput.setSelection(number.length) true } else { false @@ -203,23 +216,23 @@ class DialpadActivity : SimpleActivity() { Intent().apply { action = Intent.ACTION_INSERT_OR_EDIT type = "vnd.android.cursor.item/contact" - putExtra(KEY_PHONE, dialpad_input.value) + putExtra(KEY_PHONE, binding.dialpadInput.value) launchActivityIntent(this) } } private fun dialpadPressed(char: Char, view: View?) { - dialpad_input.addCharacter(char) + binding.dialpadInput.addCharacter(char) maybePerformDialpadHapticFeedback(view) } private fun clearChar(view: View) { - dialpad_input.dispatchKeyEvent(dialpad_input.getKeyEvent(KeyEvent.KEYCODE_DEL)) + binding.dialpadInput.dispatchKeyEvent(binding.dialpadInput.getKeyEvent(KeyEvent.KEYCODE_DEL)) maybePerformDialpadHapticFeedback(view) } private fun clearInput() { - dialpad_input.setText("") + binding.dialpadInput.setText("") } private fun gotContacts(newContacts: ArrayList) { @@ -232,7 +245,7 @@ class DialpadActivity : SimpleActivity() { } runOnUiThread { - if (!checkDialIntent() && dialpad_input.value.isEmpty()) { + if (!checkDialIntent() && binding.dialpadInput.value.isEmpty()) { dialpadValueChanged("") } } @@ -256,7 +269,7 @@ class DialpadActivity : SimpleActivity() { return } - (dialpad_list.adapter as? ContactsAdapter)?.finishActMode() + (binding.dialpadList.adapter as? ContactsAdapter)?.finishActMode() val filtered = allContacts.filter { var convertedName = PhoneNumberUtils.convertKeypadLettersToDigits(it.name.normalizeString()) @@ -275,7 +288,7 @@ class DialpadActivity : SimpleActivity() { !it.doesContainPhoneNumber(text) }).toMutableList() as ArrayList - letter_fastscroller.setupWithRecyclerView(dialpad_list, { position -> + binding.letterFastscroller.setupWithRecyclerView(binding.dialpadList, { position -> try { val name = filtered[position].getNameToDisplay() val character = if (name.isNotEmpty()) name.substring(0, 1) else "" @@ -288,7 +301,7 @@ class DialpadActivity : SimpleActivity() { ContactsAdapter( activity = this, contacts = filtered, - recyclerView = dialpad_list, + recyclerView = binding.dialpadList, highlightText = text ) { val contact = it as Contact @@ -300,21 +313,21 @@ class DialpadActivity : SimpleActivity() { startCallIntent(contact.getPrimaryNumber() ?: return@ContactsAdapter) } }.apply { - dialpad_list.adapter = this + binding.dialpadList.adapter = this } - dialpad_placeholder.beVisibleIf(filtered.isEmpty()) - dialpad_list.beVisibleIf(filtered.isNotEmpty()) + binding.dialpadPlaceholder.beVisibleIf(filtered.isEmpty()) + binding.dialpadList.beVisibleIf(filtered.isNotEmpty()) } override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) { super.onActivityResult(requestCode, resultCode, resultData) if (requestCode == REQUEST_CODE_SET_DEFAULT_DIALER && isDefaultDialer()) { - dialpadValueChanged(dialpad_input.value) + dialpadValueChanged(binding.dialpadInput.value) } } - private fun initCall(number: String = dialpad_input.value, handleIndex: Int) { + private fun initCall(number: String = binding.dialpadInput.value, handleIndex: Int) { if (number.isNotEmpty()) { if (handleIndex != -1 && areMultipleSIMsAvailable()) { if (config.showCallConfirmation) { @@ -337,7 +350,7 @@ class DialpadActivity : SimpleActivity() { } private fun speedDial(id: Int): Boolean { - if (dialpad_input.value.length == 1) { + if (binding.dialpadInput.value.length == 1) { val speedDial = speedDialValues.firstOrNull { it.id == id } if (speedDial?.isValid() == true) { initCall(speedDial.number, -1) diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/activities/MainActivity.kt index 0d9406a9..90528f2f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/activities/MainActivity.kt @@ -28,20 +28,21 @@ import com.simplemobiletools.commons.models.contacts.Contact import com.simplemobiletools.dialer.BuildConfig import com.simplemobiletools.dialer.R import com.simplemobiletools.dialer.adapters.ViewPagerAdapter +import com.simplemobiletools.dialer.databinding.ActivityMainBinding import com.simplemobiletools.dialer.dialogs.ChangeSortingDialog import com.simplemobiletools.dialer.dialogs.FilterContactSourcesDialog import com.simplemobiletools.dialer.extensions.config import com.simplemobiletools.dialer.extensions.launchCreateNewContactIntent +import com.simplemobiletools.dialer.fragments.ContactsFragment import com.simplemobiletools.dialer.fragments.FavoritesFragment import com.simplemobiletools.dialer.fragments.MyViewPagerFragment +import com.simplemobiletools.dialer.fragments.RecentsFragment import com.simplemobiletools.dialer.helpers.* -import kotlinx.android.synthetic.main.activity_main.* -import kotlinx.android.synthetic.main.fragment_contacts.* -import kotlinx.android.synthetic.main.fragment_favorites.* -import kotlinx.android.synthetic.main.fragment_recents.* import me.grantland.widget.AutofitHelper class MainActivity : SimpleActivity() { + private val binding by viewBinding(ActivityMainBinding::inflate) + private var launchedDialer = false private var storedShowTabs = 0 private var storedFontSize = 0 @@ -51,11 +52,11 @@ class MainActivity : SimpleActivity() { override fun onCreate(savedInstanceState: Bundle?) { isMaterialActivity = true super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) + setContentView(binding.root) appLaunched(BuildConfig.APPLICATION_ID) setupOptionsMenu() refreshMenuItems() - updateMaterialActivityViews(main_coordinator, main_holder, useTransparentNavigation = false, useTopSearchMenu = true) + updateMaterialActivityViews(binding.mainCoordinator, binding.mainHolder, useTransparentNavigation = false, useTopSearchMenu = true) launchedDialer = savedInstanceState?.getBoolean(OPEN_DIAL_PAD_AT_LAUNCH) ?: false @@ -63,7 +64,7 @@ class MainActivity : SimpleActivity() { checkContactPermissions() if (!config.wasOverlaySnackbarConfirmed && !Settings.canDrawOverlays(this)) { - val snackbar = Snackbar.make(main_holder, R.string.allow_displaying_over_other_apps, Snackbar.LENGTH_INDEFINITE).setAction(R.string.ok) { + val snackbar = Snackbar.make(binding.mainHolder, R.string.allow_displaying_over_other_apps, Snackbar.LENGTH_INDEFINITE).setAction(R.string.ok) { config.wasOverlaySnackbarConfirmed = true startActivity(Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)) } @@ -102,9 +103,9 @@ class MainActivity : SimpleActivity() { updateMenuColors() val properPrimaryColor = getProperPrimaryColor() val dialpadIcon = resources.getColoredDrawableWithColor(R.drawable.ic_dialpad_vector, properPrimaryColor.getContrastColor()) - main_dialpad_button.setImageDrawable(dialpadIcon) + binding.mainDialpadButton.setImageDrawable(dialpadIcon) - updateTextColors(main_holder) + updateTextColors(binding.mainHolder) setupTabColors() getAllFragments().forEach { @@ -113,12 +114,12 @@ class MainActivity : SimpleActivity() { val configStartNameWithSurname = config.startNameWithSurname if (storedStartNameWithSurname != configStartNameWithSurname) { - contacts_fragment?.startNameWithSurnameChanged(configStartNameWithSurname) - favorites_fragment?.startNameWithSurnameChanged(configStartNameWithSurname) + getContactsFragment()?.startNameWithSurnameChanged(configStartNameWithSurname) + getFavoritesFragment()?.startNameWithSurnameChanged(configStartNameWithSurname) storedStartNameWithSurname = config.startNameWithSurname } - if (!main_menu.isSearchOpen) { + if (!binding.mainMenu.isSearchOpen) { refreshItems(true) } @@ -131,7 +132,7 @@ class MainActivity : SimpleActivity() { checkShortcuts() Handler().postDelayed({ - recents_fragment?.refreshItems() + getRecentsFragment()?.refreshItems() }, 2000) } @@ -139,7 +140,7 @@ class MainActivity : SimpleActivity() { super.onPause() storedShowTabs = config.showTabs storedStartNameWithSurname = config.startNameWithSurname - config.lastUsedViewPagerPage = view_pager.currentItem + config.lastUsedViewPagerPage = binding.viewPager.currentItem } override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) { @@ -165,8 +166,8 @@ class MainActivity : SimpleActivity() { } override fun onBackPressed() { - if (main_menu.isSearchOpen) { - main_menu.closeSearch() + if (binding.mainMenu.isSearchOpen) { + binding.mainMenu.closeSearch() } else { super.onBackPressed() } @@ -174,45 +175,47 @@ class MainActivity : SimpleActivity() { private fun refreshMenuItems() { val currentFragment = getCurrentFragment() - main_menu.getToolbar().menu.apply { - findItem(R.id.clear_call_history).isVisible = currentFragment == recents_fragment - findItem(R.id.sort).isVisible = currentFragment != recents_fragment - findItem(R.id.create_new_contact).isVisible = currentFragment == contacts_fragment - findItem(R.id.change_view_type).isVisible = currentFragment == favorites_fragment - findItem(R.id.column_count).isVisible = currentFragment == favorites_fragment && config.viewType == VIEW_TYPE_GRID + binding.mainMenu.getToolbar().menu.apply { + findItem(R.id.clear_call_history).isVisible = currentFragment == getRecentsFragment() + findItem(R.id.sort).isVisible = currentFragment != getRecentsFragment() + findItem(R.id.create_new_contact).isVisible = currentFragment == getContactsFragment() + findItem(R.id.change_view_type).isVisible = currentFragment == getFavoritesFragment() + findItem(R.id.column_count).isVisible = currentFragment == getFavoritesFragment() && config.viewType == VIEW_TYPE_GRID findItem(R.id.more_apps_from_us).isVisible = !resources.getBoolean(R.bool.hide_google_relations) } } private fun setupOptionsMenu() { - main_menu.getToolbar().inflateMenu(R.menu.menu) - main_menu.toggleHideOnScroll(false) - main_menu.setupMenu() + binding.mainMenu.apply { + getToolbar().inflateMenu(R.menu.menu) + toggleHideOnScroll(false) + setupMenu() - main_menu.onSearchClosedListener = { - getAllFragments().forEach { - it?.onSearchQueryChanged("") + onSearchClosedListener = { + getAllFragments().forEach { + it?.onSearchQueryChanged("") + } } - } - main_menu.onSearchTextChangedListener = { text -> - getCurrentFragment()?.onSearchQueryChanged(text) - } - - main_menu.getToolbar().setOnMenuItemClickListener { menuItem -> - when (menuItem.itemId) { - R.id.clear_call_history -> clearCallHistory() - R.id.create_new_contact -> launchCreateNewContactIntent() - R.id.sort -> showSortingDialog(showCustomSorting = getCurrentFragment() is FavoritesFragment) - R.id.filter -> showFilterDialog() - R.id.more_apps_from_us -> launchMoreAppsFromUsIntent() - R.id.settings -> launchSettings() - R.id.change_view_type -> changeViewType() - R.id.column_count -> changeColumnCount() - R.id.about -> launchAbout() - else -> return@setOnMenuItemClickListener false + onSearchTextChangedListener = { text -> + getCurrentFragment()?.onSearchQueryChanged(text) + } + + getToolbar().setOnMenuItemClickListener { menuItem -> + when (menuItem.itemId) { + R.id.clear_call_history -> clearCallHistory() + R.id.create_new_contact -> launchCreateNewContactIntent() + R.id.sort -> showSortingDialog(showCustomSorting = getCurrentFragment() is FavoritesFragment) + R.id.filter -> showFilterDialog() + R.id.more_apps_from_us -> launchMoreAppsFromUsIntent() + R.id.settings -> launchSettings() + R.id.change_view_type -> changeViewType() + R.id.column_count -> changeColumnCount() + R.id.about -> launchAbout() + else -> return@setOnMenuItemClickListener false + } + return@setOnMenuItemClickListener true } - return@setOnMenuItemClickListener true } } @@ -227,7 +230,7 @@ class MainActivity : SimpleActivity() { val newColumnCount = it as Int if (currentColumnCount != newColumnCount) { config.contactsGridColumnCount = newColumnCount - favorites_fragment?.columnCountChanged() + getFavoritesFragment()?.columnCountChanged() } } } @@ -235,13 +238,13 @@ class MainActivity : SimpleActivity() { private fun changeViewType() { ChangeViewTypeDialog(this) { refreshMenuItems() - favorites_fragment?.refreshItems() + getFavoritesFragment()?.refreshItems() } } private fun updateMenuColors() { updateStatusbarColor(getProperBackgroundColor()) - main_menu.updateColors() + binding.mainMenu.updateColors() } private fun checkContactPermissions() { @@ -255,7 +258,7 @@ class MainActivity : SimpleActivity() { ConfirmationDialog(this, confirmationText) { RecentsHelper(this).removeAllRecentCalls(this) { runOnUiThread { - recents_fragment?.refreshItems() + getRecentsFragment()?.refreshItems() } } } @@ -293,20 +296,20 @@ class MainActivity : SimpleActivity() { } private fun setupTabColors() { - val activeView = main_tabs_holder.getTabAt(view_pager.currentItem)?.customView - updateBottomTabItemColors(activeView, true, getSelectedTabDrawableIds()[view_pager.currentItem]) + val activeView = binding.mainTabsHolder.getTabAt(binding.viewPager.currentItem)?.customView + updateBottomTabItemColors(activeView, true, getSelectedTabDrawableIds()[binding.viewPager.currentItem]) - getInactiveTabIndexes(view_pager.currentItem).forEach { index -> - val inactiveView = main_tabs_holder.getTabAt(index)?.customView + getInactiveTabIndexes(binding.viewPager.currentItem).forEach { index -> + val inactiveView = binding.mainTabsHolder.getTabAt(index)?.customView updateBottomTabItemColors(inactiveView, false, getDeselectedTabDrawableIds()[index]) } val bottomBarColor = getBottomNavigationBackgroundColor() - main_tabs_holder.setBackgroundColor(bottomBarColor) + binding.mainTabsHolder.setBackgroundColor(bottomBarColor) updateNavigationBarColor(bottomBarColor) } - private fun getInactiveTabIndexes(activeIndex: Int) = (0 until main_tabs_holder.tabCount).filter { it != activeIndex } + private fun getInactiveTabIndexes(activeIndex: Int) = (0 until binding.mainTabsHolder.tabCount).filter { it != activeIndex } private fun getSelectedTabDrawableIds(): List { val showTabs = config.showTabs @@ -347,14 +350,14 @@ class MainActivity : SimpleActivity() { } private fun initFragments() { - view_pager.offscreenPageLimit = 2 - view_pager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + binding.viewPager.offscreenPageLimit = 2 + binding.viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { override fun onPageScrollStateChanged(state: Int) {} override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {} override fun onPageSelected(position: Int) { - main_tabs_holder.getTabAt(position)?.select() + binding.mainTabsHolder.getTabAt(position)?.select() getAllFragments().forEach { it?.finishActMode() } @@ -363,29 +366,29 @@ class MainActivity : SimpleActivity() { }) // selecting the proper tab sometimes glitches, add an extra selector to make sure we have it right - main_tabs_holder.onGlobalLayout { + binding.mainTabsHolder.onGlobalLayout { Handler().postDelayed({ var wantedTab = getDefaultTab() // open the Recents tab if we got here by clicking a missed call notification if (intent.action == Intent.ACTION_VIEW && config.showTabs and TAB_CALL_HISTORY > 0) { - wantedTab = main_tabs_holder.tabCount - 1 + wantedTab = binding.mainTabsHolder.tabCount - 1 ensureBackgroundThread { clearMissedCalls() } } - main_tabs_holder.getTabAt(wantedTab)?.select() + binding.mainTabsHolder.getTabAt(wantedTab)?.select() refreshMenuItems() }, 100L) } - main_dialpad_button.setOnClickListener { + binding.mainDialpadButton.setOnClickListener { launchDialpad() } - view_pager.onGlobalLayout { + binding.viewPager.onGlobalLayout { refreshMenuItems() } @@ -396,31 +399,31 @@ class MainActivity : SimpleActivity() { } private fun setupTabs() { - view_pager.adapter = null - main_tabs_holder.removeAllTabs() + binding.viewPager.adapter = null + binding.mainTabsHolder.removeAllTabs() tabsList.forEachIndexed { index, value -> if (config.showTabs and value != 0) { - main_tabs_holder.newTab().setCustomView(R.layout.bottom_tablayout_item).apply { + binding.mainTabsHolder.newTab().setCustomView(R.layout.bottom_tablayout_item).apply { customView?.findViewById(R.id.tab_item_icon)?.setImageDrawable(getTabIcon(index)) customView?.findViewById(R.id.tab_item_label)?.text = getTabLabel(index) AutofitHelper.create(customView?.findViewById(R.id.tab_item_label)) - main_tabs_holder.addTab(this) + binding.mainTabsHolder.addTab(this) } } } - main_tabs_holder.onTabSelectionChanged( + binding.mainTabsHolder.onTabSelectionChanged( tabUnselectedAction = { updateBottomTabItemColors(it.customView, false, getDeselectedTabDrawableIds()[it.position]) }, tabSelectedAction = { - main_menu.closeSearch() - view_pager.currentItem = it.position + binding.mainMenu.closeSearch() + binding.viewPager.currentItem = it.position updateBottomTabItemColors(it.customView, true, getSelectedTabDrawableIds()[it.position]) } ) - main_tabs_holder.beGoneIf(main_tabs_holder.tabCount == 1) + binding.mainTabsHolder.beGoneIf(binding.mainTabsHolder.tabCount == 1) storedShowTabs = config.showTabs storedStartNameWithSurname = config.startNameWithSurname } @@ -450,14 +453,16 @@ class MainActivity : SimpleActivity() { return } - if (view_pager.adapter == null) { - view_pager.adapter = ViewPagerAdapter(this) - view_pager.currentItem = if (openLastTab) config.lastUsedViewPagerPage else getDefaultTab() - view_pager.onGlobalLayout { + binding.apply { + if (viewPager.adapter == null) { + viewPager.adapter = ViewPagerAdapter(this@MainActivity) + viewPager.currentItem = if (openLastTab) config.lastUsedViewPagerPage else getDefaultTab() + viewPager.onGlobalLayout { + refreshFragments() + } + } else { refreshFragments() } - } else { - refreshFragments() } } @@ -468,36 +473,42 @@ class MainActivity : SimpleActivity() { } fun refreshFragments() { - contacts_fragment?.refreshItems() - favorites_fragment?.refreshItems() - recents_fragment?.refreshItems() + getContactsFragment()?.refreshItems() + getFavoritesFragment()?.refreshItems() + getRecentsFragment()?.refreshItems() } - private fun getAllFragments(): ArrayList { + private fun getAllFragments(): ArrayList?> { val showTabs = config.showTabs - val fragments = arrayListOf() + val fragments = arrayListOf?>() if (showTabs and TAB_CONTACTS > 0) { - fragments.add(contacts_fragment) + fragments.add(getContactsFragment()) } if (showTabs and TAB_FAVORITES > 0) { - fragments.add(favorites_fragment) + fragments.add(getFavoritesFragment()) } if (showTabs and TAB_CALL_HISTORY > 0) { - fragments.add(recents_fragment) + fragments.add(getRecentsFragment()) } return fragments } - private fun getCurrentFragment(): MyViewPagerFragment? = getAllFragments().getOrNull(view_pager.currentItem) + private fun getCurrentFragment(): MyViewPagerFragment<*>? = getAllFragments().getOrNull(binding.viewPager.currentItem) + + private fun getContactsFragment(): ContactsFragment? = findViewById(R.id.contacts_fragment) + + private fun getFavoritesFragment(): FavoritesFragment? = findViewById(R.id.favorites_fragment) + + private fun getRecentsFragment(): RecentsFragment? = findViewById(R.id.recents_fragment) private fun getDefaultTab(): Int { val showTabsMask = config.showTabs return when (config.defaultTab) { - TAB_LAST_USED -> if (config.lastUsedViewPagerPage < main_tabs_holder.tabCount) config.lastUsedViewPagerPage else 0 + TAB_LAST_USED -> if (config.lastUsedViewPagerPage < binding.mainTabsHolder.tabCount) config.lastUsedViewPagerPage else 0 TAB_CONTACTS -> 0 TAB_FAVORITES -> if (showTabsMask and TAB_CONTACTS > 0) 1 else 0 else -> { @@ -556,15 +567,15 @@ class MainActivity : SimpleActivity() { private fun showSortingDialog(showCustomSorting: Boolean) { ChangeSortingDialog(this, showCustomSorting) { - favorites_fragment?.refreshItems { - if (main_menu.isSearchOpen) { - getCurrentFragment()?.onSearchQueryChanged(main_menu.getCurrentQuery()) + getFavoritesFragment()?.refreshItems { + if (binding.mainMenu.isSearchOpen) { + getCurrentFragment()?.onSearchQueryChanged(binding.mainMenu.getCurrentQuery()) } } - contacts_fragment?.refreshItems { - if (main_menu.isSearchOpen) { - getCurrentFragment()?.onSearchQueryChanged(main_menu.getCurrentQuery()) + getContactsFragment()?.refreshItems { + if (binding.mainMenu.isSearchOpen) { + getCurrentFragment()?.onSearchQueryChanged(binding.mainMenu.getCurrentQuery()) } } } @@ -572,21 +583,21 @@ class MainActivity : SimpleActivity() { private fun showFilterDialog() { FilterContactSourcesDialog(this) { - favorites_fragment?.refreshItems { - if (main_menu.isSearchOpen) { - getCurrentFragment()?.onSearchQueryChanged(main_menu.getCurrentQuery()) + getFavoritesFragment()?.refreshItems { + if (binding.mainMenu.isSearchOpen) { + getCurrentFragment()?.onSearchQueryChanged(binding.mainMenu.getCurrentQuery()) } } - contacts_fragment?.refreshItems { - if (main_menu.isSearchOpen) { - getCurrentFragment()?.onSearchQueryChanged(main_menu.getCurrentQuery()) + getContactsFragment()?.refreshItems { + if (binding.mainMenu.isSearchOpen) { + getCurrentFragment()?.onSearchQueryChanged(binding.mainMenu.getCurrentQuery()) } } - recents_fragment?.refreshItems { - if (main_menu.isSearchOpen) { - getCurrentFragment()?.onSearchQueryChanged(main_menu.getCurrentQuery()) + getRecentsFragment()?.refreshItems { + if (binding.mainMenu.isSearchOpen) { + getCurrentFragment()?.onSearchQueryChanged(binding.mainMenu.getCurrentQuery()) } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/activities/ManageSpeedDialActivity.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/activities/ManageSpeedDialActivity.kt index c4d5aefc..2e7959fc 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/activities/ManageSpeedDialActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/activities/ManageSpeedDialActivity.kt @@ -5,31 +5,36 @@ import com.google.gson.Gson import com.simplemobiletools.commons.dialogs.RadioGroupDialog import com.simplemobiletools.commons.extensions.getMyContactsCursor import com.simplemobiletools.commons.extensions.updateTextColors +import com.simplemobiletools.commons.extensions.viewBinding import com.simplemobiletools.commons.helpers.ContactsHelper import com.simplemobiletools.commons.helpers.MyContactsContentProvider import com.simplemobiletools.commons.helpers.NavigationIcon import com.simplemobiletools.commons.models.PhoneNumber import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.commons.models.contacts.Contact -import com.simplemobiletools.dialer.R import com.simplemobiletools.dialer.adapters.SpeedDialAdapter +import com.simplemobiletools.dialer.databinding.ActivityManageSpeedDialBinding import com.simplemobiletools.dialer.dialogs.SelectContactDialog import com.simplemobiletools.dialer.extensions.config import com.simplemobiletools.dialer.interfaces.RemoveSpeedDialListener import com.simplemobiletools.dialer.models.SpeedDial -import kotlinx.android.synthetic.main.activity_manage_speed_dial.* class ManageSpeedDialActivity : SimpleActivity(), RemoveSpeedDialListener { + private val binding by viewBinding(ActivityManageSpeedDialBinding::inflate) + private var allContacts = mutableListOf() private var speedDialValues = mutableListOf() override fun onCreate(savedInstanceState: Bundle?) { isMaterialActivity = true super.onCreate(savedInstanceState) - setContentView(R.layout.activity_manage_speed_dial) + setContentView(binding.root) - updateMaterialActivityViews(manage_speed_dial_coordinator, manage_speed_dial_holder, useTransparentNavigation = true, useTopSearchMenu = false) - setupMaterialScrollListener(manage_speed_dial_scrollview, manage_speed_dial_toolbar) + binding.apply { + updateMaterialActivityViews(manageSpeedDialCoordinator, manageSpeedDialHolder, useTransparentNavigation = true, useTopSearchMenu = false) + setupMaterialScrollListener(manageSpeedDialScrollview, manageSpeedDialToolbar) + + } speedDialValues = config.getSpeedDialValues() updateAdapter() @@ -43,12 +48,12 @@ class ManageSpeedDialActivity : SimpleActivity(), RemoveSpeedDialListener { allContacts.sort() } - updateTextColors(manage_speed_dial_scrollview) + updateTextColors(binding.manageSpeedDialScrollview) } override fun onResume() { super.onResume() - setupToolbar(manage_speed_dial_toolbar, NavigationIcon.Arrow) + setupToolbar(binding.manageSpeedDialToolbar, NavigationIcon.Arrow) } override fun onStop() { @@ -57,7 +62,7 @@ class ManageSpeedDialActivity : SimpleActivity(), RemoveSpeedDialListener { } private fun updateAdapter() { - SpeedDialAdapter(this, speedDialValues, this, speed_dial_list) { + SpeedDialAdapter(this, speedDialValues, this, binding.speedDialList) { val clickedContact = it as SpeedDial if (allContacts.isEmpty()) { return@SpeedDialAdapter @@ -88,7 +93,7 @@ class ManageSpeedDialActivity : SimpleActivity(), RemoveSpeedDialListener { } }.apply { - speed_dial_list.adapter = this + binding.speedDialList.adapter = this } } diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/activities/SettingsActivity.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/activities/SettingsActivity.kt index db6cf531..cc130cc5 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/activities/SettingsActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/activities/SettingsActivity.kt @@ -15,23 +15,24 @@ import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.dialer.R +import com.simplemobiletools.dialer.databinding.ActivitySettingsBinding import com.simplemobiletools.dialer.dialogs.ExportCallHistoryDialog import com.simplemobiletools.dialer.dialogs.ManageVisibleTabsDialog import com.simplemobiletools.dialer.extensions.config import com.simplemobiletools.dialer.helpers.RecentsHelper import com.simplemobiletools.dialer.models.RecentCall -import kotlinx.android.synthetic.main.activity_settings.* import kotlinx.serialization.SerializationException -import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import java.util.* import kotlin.system.exitProcess class SettingsActivity : SimpleActivity() { + companion object { + private const val CALL_HISTORY_FILE_TYPE = "application/json" + } - private val callHistoryFileType = "application/json" - + private val binding by viewBinding(ActivitySettingsBinding::inflate) private val getContent = registerForActivityResult(ActivityResultContracts.GetContent()) { uri -> if (uri != null) { toast(R.string.importing) @@ -39,7 +40,7 @@ class SettingsActivity : SimpleActivity() { } } - private val saveDocument = registerForActivityResult(ActivityResultContracts.CreateDocument(callHistoryFileType)) { uri -> + private val saveDocument = registerForActivityResult(ActivityResultContracts.CreateDocument(CALL_HISTORY_FILE_TYPE)) { uri -> if (uri != null) { toast(R.string.exporting) RecentsHelper(this).getRecentCalls(false, Int.MAX_VALUE) { recents -> @@ -51,15 +52,17 @@ class SettingsActivity : SimpleActivity() { override fun onCreate(savedInstanceState: Bundle?) { isMaterialActivity = true super.onCreate(savedInstanceState) - setContentView(R.layout.activity_settings) + setContentView(binding.root) - updateMaterialActivityViews(settings_coordinator, settings_holder, useTransparentNavigation = true, useTopSearchMenu = false) - setupMaterialScrollListener(settings_nested_scrollview, settings_toolbar) + binding.apply { + updateMaterialActivityViews(settingsCoordinator, settingsHolder, useTransparentNavigation = true, useTopSearchMenu = false) + setupMaterialScrollListener(settingsNestedScrollview, settingsToolbar) + } } override fun onResume() { super.onResume() - setupToolbar(settings_toolbar, NavigationIcon.Arrow) + setupToolbar(binding.settingsToolbar, NavigationIcon.Arrow) setupPurchaseThankYou() setupCustomizeColors() @@ -83,16 +86,18 @@ class SettingsActivity : SimpleActivity() { setupAlwaysShowFullscreen() setupCallsExport() setupCallsImport() - updateTextColors(settings_holder) + updateTextColors(binding.settingsHolder) - arrayOf( - settings_color_customization_section_label, - settings_general_settings_label, - settings_startup_label, - settings_calls_label, - settings_migration_section_label - ).forEach { - it.setTextColor(getProperPrimaryColor()) + binding.apply { + arrayOf( + settingsColorCustomizationSectionLabel, + settingsGeneralSettingsLabel, + settingsStartupLabel, + settingsCallsLabel, + settingsMigrationSectionLabel + ).forEach { + it.setTextColor(getProperPrimaryColor()) + } } } @@ -102,55 +107,61 @@ class SettingsActivity : SimpleActivity() { } private fun setupPurchaseThankYou() { - settings_purchase_thank_you_holder.beGoneIf(isOrWasThankYouInstalled()) - settings_purchase_thank_you_holder.setOnClickListener { + binding.settingsPurchaseThankYouHolder.beGoneIf(isOrWasThankYouInstalled()) + binding.settingsPurchaseThankYouHolder.setOnClickListener { launchPurchaseThankYouIntent() } } private fun setupCustomizeColors() { - settings_color_customization_label.text = getCustomizeColorsString() - settings_color_customization_holder.setOnClickListener { + binding.settingsColorCustomizationLabel.text = getCustomizeColorsString() + binding.settingsColorCustomizationHolder.setOnClickListener { handleCustomizeColorsClick() } } private fun setupUseEnglish() { - settings_use_english_holder.beVisibleIf((config.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus()) - settings_use_english.isChecked = config.useEnglish - settings_use_english_holder.setOnClickListener { - settings_use_english.toggle() - config.useEnglish = settings_use_english.isChecked - exitProcess(0) + binding.apply { + settingsUseEnglishHolder.beVisibleIf((config.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus()) + settingsUseEnglish.isChecked = config.useEnglish + settingsUseEnglishHolder.setOnClickListener { + settingsUseEnglish.toggle() + config.useEnglish = settingsUseEnglish.isChecked + exitProcess(0) + } } } private fun setupLanguage() { - settings_language.text = Locale.getDefault().displayLanguage - settings_language_holder.beVisibleIf(isTiramisuPlus()) - settings_language_holder.setOnClickListener { - launchChangeAppLanguageIntent() + binding.apply { + settingsLanguage.text = Locale.getDefault().displayLanguage + settingsLanguageHolder.beVisibleIf(isTiramisuPlus()) + settingsLanguageHolder.setOnClickListener { + launchChangeAppLanguageIntent() + } } } // support for device-wise blocking came on Android 7, rely only on that @TargetApi(Build.VERSION_CODES.N) private fun setupManageBlockedNumbers() { - settings_manage_blocked_numbers_label.text = addLockedLabelIfNeeded(R.string.manage_blocked_numbers) - settings_manage_blocked_numbers_holder.beVisibleIf(isNougatPlus()) - settings_manage_blocked_numbers_holder.setOnClickListener { - if (isOrWasThankYouInstalled()) { - Intent(this, ManageBlockedNumbersActivity::class.java).apply { - startActivity(this) + binding.apply { + settingsManageBlockedNumbersLabel.text = addLockedLabelIfNeeded(R.string.manage_blocked_numbers) + settingsManageBlockedNumbersHolder.beVisibleIf(isNougatPlus()) + settingsManageBlockedNumbersHolder.setOnClickListener { + if (isOrWasThankYouInstalled()) { + Intent(this@SettingsActivity, ManageBlockedNumbersActivity::class.java).apply { + startActivity(this) + } + } else { + FeatureLockedDialog(this@SettingsActivity) { } } - } else { - FeatureLockedDialog(this) { } } } } private fun setupManageSpeedDial() { - settings_manage_speed_dial_holder.setOnClickListener { + binding.settingsManageSpeedDialHolder.setOnClickListener { Intent(this, ManageSpeedDialActivity::class.java).apply { startActivity(this) } @@ -158,14 +169,14 @@ class SettingsActivity : SimpleActivity() { } private fun setupChangeDateTimeFormat() { - settings_change_date_time_format_holder.setOnClickListener { + binding.settingsChangeDateTimeFormatHolder.setOnClickListener { ChangeDateTimeFormatDialog(this) {} } } private fun setupFontSize() { - settings_font_size.text = getFontSizeText() - settings_font_size_holder.setOnClickListener { + binding.settingsFontSize.text = getFontSizeText() + binding.settingsFontSizeHolder.setOnClickListener { val items = arrayListOf( RadioItem(FONT_SIZE_SMALL, getString(R.string.small)), RadioItem(FONT_SIZE_MEDIUM, getString(R.string.medium)), @@ -175,20 +186,20 @@ class SettingsActivity : SimpleActivity() { RadioGroupDialog(this@SettingsActivity, items, config.fontSize) { config.fontSize = it as Int - settings_font_size.text = getFontSizeText() + binding.settingsFontSize.text = getFontSizeText() } } } private fun setupManageShownTabs() { - settings_manage_tabs_holder.setOnClickListener { + binding.settingsManageTabsHolder.setOnClickListener { ManageVisibleTabsDialog(this) } } private fun setupDefaultTab() { - settings_default_tab.text = getDefaultTabText() - settings_default_tab_holder.setOnClickListener { + binding.settingsDefaultTab.text = getDefaultTabText() + binding.settingsDefaultTabHolder.setOnClickListener { val items = arrayListOf( RadioItem(TAB_CONTACTS, getString(R.string.contacts_tab)), RadioItem(TAB_FAVORITES, getString(R.string.favorites_tab)), @@ -198,7 +209,7 @@ class SettingsActivity : SimpleActivity() { RadioGroupDialog(this@SettingsActivity, items, config.defaultTab) { config.defaultTab = it as Int - settings_default_tab.text = getDefaultTabText() + binding.settingsDefaultTab.text = getDefaultTabText() } } } @@ -213,87 +224,107 @@ class SettingsActivity : SimpleActivity() { ) private fun setupDialPadOpen() { - settings_open_dialpad_at_launch.isChecked = config.openDialPadAtLaunch - settings_open_dialpad_at_launch_holder.setOnClickListener { - settings_open_dialpad_at_launch.toggle() - config.openDialPadAtLaunch = settings_open_dialpad_at_launch.isChecked + binding.apply { + settingsOpenDialpadAtLaunch.isChecked = config.openDialPadAtLaunch + settingsOpenDialpadAtLaunchHolder.setOnClickListener { + settingsOpenDialpadAtLaunch.toggle() + config.openDialPadAtLaunch = settingsOpenDialpadAtLaunch.isChecked + } } } private fun setupGroupSubsequentCalls() { - settings_group_subsequent_calls.isChecked = config.groupSubsequentCalls - settings_group_subsequent_calls_holder.setOnClickListener { - settings_group_subsequent_calls.toggle() - config.groupSubsequentCalls = settings_group_subsequent_calls.isChecked + binding.apply { + settingsGroupSubsequentCalls.isChecked = config.groupSubsequentCalls + settingsGroupSubsequentCallsHolder.setOnClickListener { + settingsGroupSubsequentCalls.toggle() + config.groupSubsequentCalls = settingsGroupSubsequentCalls.isChecked + } } } private fun setupStartNameWithSurname() { - settings_start_name_with_surname.isChecked = config.startNameWithSurname - settings_start_name_with_surname_holder.setOnClickListener { - settings_start_name_with_surname.toggle() - config.startNameWithSurname = settings_start_name_with_surname.isChecked + binding.apply { + settingsStartNameWithSurname.isChecked = config.startNameWithSurname + settingsStartNameWithSurnameHolder.setOnClickListener { + settingsStartNameWithSurname.toggle() + config.startNameWithSurname = settingsStartNameWithSurname.isChecked + } } } private fun setupDialpadVibrations() { - settings_dialpad_vibration.isChecked = config.dialpadVibration - settings_dialpad_vibration_holder.setOnClickListener { - settings_dialpad_vibration.toggle() - config.dialpadVibration = settings_dialpad_vibration.isChecked + binding.apply { + settingsDialpadVibration.isChecked = config.dialpadVibration + settingsDialpadVibrationHolder.setOnClickListener { + settingsDialpadVibration.toggle() + config.dialpadVibration = settingsDialpadVibration.isChecked + } } } private fun setupDialpadNumbers() { - settings_hide_dialpad_numbers.isChecked = config.hideDialpadNumbers - settings_hide_dialpad_numbers_holder.setOnClickListener { - settings_hide_dialpad_numbers.toggle() - config.hideDialpadNumbers = settings_hide_dialpad_numbers.isChecked + binding.apply { + settingsHideDialpadNumbers.isChecked = config.hideDialpadNumbers + settingsHideDialpadNumbersHolder.setOnClickListener { + settingsHideDialpadNumbers.toggle() + config.hideDialpadNumbers = settingsHideDialpadNumbers.isChecked + } } } private fun setupDialpadBeeps() { - settings_dialpad_beeps.isChecked = config.dialpadBeeps - settings_dialpad_beeps_holder.setOnClickListener { - settings_dialpad_beeps.toggle() - config.dialpadBeeps = settings_dialpad_beeps.isChecked + binding.apply { + settingsDialpadBeeps.isChecked = config.dialpadBeeps + settingsDialpadBeepsHolder.setOnClickListener { + settingsDialpadBeeps.toggle() + config.dialpadBeeps = settingsDialpadBeeps.isChecked + } } } private fun setupShowCallConfirmation() { - settings_show_call_confirmation.isChecked = config.showCallConfirmation - settings_show_call_confirmation_holder.setOnClickListener { - settings_show_call_confirmation.toggle() - config.showCallConfirmation = settings_show_call_confirmation.isChecked + binding.apply { + settingsShowCallConfirmation.isChecked = config.showCallConfirmation + settingsShowCallConfirmationHolder.setOnClickListener { + settingsShowCallConfirmation.toggle() + config.showCallConfirmation = settingsShowCallConfirmation.isChecked + } } } private fun setupDisableProximitySensor() { - settings_disable_proximity_sensor.isChecked = config.disableProximitySensor - settings_disable_proximity_sensor_holder.setOnClickListener { - settings_disable_proximity_sensor.toggle() - config.disableProximitySensor = settings_disable_proximity_sensor.isChecked + binding.apply { + settingsDisableProximitySensor.isChecked = config.disableProximitySensor + settingsDisableProximitySensorHolder.setOnClickListener { + settingsDisableProximitySensor.toggle() + config.disableProximitySensor = settingsDisableProximitySensor.isChecked + } } } private fun setupDisableSwipeToAnswer() { - settings_disable_swipe_to_answer.isChecked = config.disableSwipeToAnswer - settings_disable_swipe_to_answer_holder.setOnClickListener { - settings_disable_swipe_to_answer.toggle() - config.disableSwipeToAnswer = settings_disable_swipe_to_answer.isChecked + binding.apply { + settingsDisableSwipeToAnswer.isChecked = config.disableSwipeToAnswer + settingsDisableSwipeToAnswerHolder.setOnClickListener { + settingsDisableSwipeToAnswer.toggle() + config.disableSwipeToAnswer = settingsDisableSwipeToAnswer.isChecked + } } } private fun setupAlwaysShowFullscreen() { - settings_always_show_fullscreen.isChecked = config.alwaysShowFullscreen - settings_always_show_fullscreen_holder.setOnClickListener { - settings_always_show_fullscreen.toggle() - config.alwaysShowFullscreen = settings_always_show_fullscreen.isChecked + binding.apply { + settingsAlwaysShowFullscreen.isChecked = config.alwaysShowFullscreen + settingsAlwaysShowFullscreenHolder.setOnClickListener { + settingsAlwaysShowFullscreen.toggle() + config.alwaysShowFullscreen = settingsAlwaysShowFullscreen.isChecked + } } } private fun setupCallsExport() { - settings_export_calls_holder.setOnClickListener { + binding.settingsExportCallsHolder.setOnClickListener { ExportCallHistoryDialog(this) { filename -> saveDocument.launch(filename) } @@ -301,8 +332,8 @@ class SettingsActivity : SimpleActivity() { } private fun setupCallsImport() { - settings_import_calls_holder.setOnClickListener { - getContent.launch(callHistoryFileType) + binding.settingsImportCallsHolder.setOnClickListener { + getContent.launch(CALL_HISTORY_FILE_TYPE) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/ConferenceCallsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/ConferenceCallsAdapter.kt index 60d9df8b..80f3db8b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/ConferenceCallsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/ConferenceCallsAdapter.kt @@ -11,9 +11,9 @@ import com.simplemobiletools.commons.helpers.SimpleContactsHelper import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.dialer.R import com.simplemobiletools.dialer.activities.SimpleActivity +import com.simplemobiletools.dialer.databinding.ItemConferenceCallBinding import com.simplemobiletools.dialer.extensions.hasCapability import com.simplemobiletools.dialer.helpers.getCallContact -import kotlinx.android.synthetic.main.item_conference_call.view.* class ConferenceCallsAdapter( activity: SimpleActivity, recyclerView: MyRecyclerView, val data: ArrayList, itemClick: (Any) -> Unit @@ -39,55 +39,63 @@ class ConferenceCallsAdapter( override fun prepareActionMode(menu: Menu) {} - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_conference_call, parent) + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return createViewHolder(ItemConferenceCallBinding.inflate(layoutInflater, parent, false).root) + } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val call = data[position] holder.bindView(call, allowSingleClick = false, allowLongClick = false) { itemView, _ -> - getCallContact(itemView.context, call) { callContact -> - itemView.post { - itemView.item_conference_call_name.text = callContact.name.ifEmpty { itemView.context.getString(R.string.unknown_caller) } - SimpleContactsHelper(activity).loadContactImage( - callContact.photoUri, - itemView.item_conference_call_image, - callContact.name, - activity.getDrawable(R.drawable.ic_person_vector) - ) + ItemConferenceCallBinding.bind(itemView).apply { + getCallContact(itemView.context, call) { callContact -> + root.post { + itemConferenceCallName.text = callContact.name.ifEmpty { itemView.context.getString(R.string.unknown_caller) } + SimpleContactsHelper(activity).loadContactImage( + callContact.photoUri, + itemConferenceCallImage, + callContact.name, + activity.getDrawable(R.drawable.ic_person_vector) + ) + } } - } - val canSeparate = call.hasCapability(Call.Details.CAPABILITY_SEPARATE_FROM_CONFERENCE) - val canDisconnect = call.hasCapability(Call.Details.CAPABILITY_DISCONNECT_FROM_CONFERENCE) - itemView.item_conference_call_split.isEnabled = canSeparate - itemView.item_conference_call_split.alpha = if (canSeparate) 1.0f else LOWER_ALPHA - itemView.item_conference_call_split.setOnClickListener { - call.splitFromConference() - data.removeAt(position) - notifyItemRemoved(position) - if (data.size == 1) { - activity.finish() + + val canSeparate = call.hasCapability(Call.Details.CAPABILITY_SEPARATE_FROM_CONFERENCE) + val canDisconnect = call.hasCapability(Call.Details.CAPABILITY_DISCONNECT_FROM_CONFERENCE) + itemConferenceCallSplit.isEnabled = canSeparate + itemConferenceCallSplit.alpha = if (canSeparate) 1.0f else LOWER_ALPHA + itemConferenceCallSplit.setOnClickListener { + call.splitFromConference() + data.removeAt(position) + notifyItemRemoved(position) + if (data.size == 1) { + activity.finish() + } } - } - itemView.item_conference_call_split.setOnLongClickListener { - if (!it.contentDescription.isNullOrEmpty()) { - itemView.context.toast(it.contentDescription.toString()) + + itemConferenceCallSplit.setOnLongClickListener { + if (!it.contentDescription.isNullOrEmpty()) { + root.context.toast(it.contentDescription.toString()) + } + true } - true - } - itemView.item_conference_call_end.isEnabled = canDisconnect - itemView.item_conference_call_end.alpha = if (canDisconnect) 1.0f else LOWER_ALPHA - itemView.item_conference_call_end.setOnClickListener { - call.disconnect() - data.removeAt(position) - notifyItemRemoved(position) - if (data.size == 1) { - activity.finish() + + itemConferenceCallEnd.isEnabled = canDisconnect + itemConferenceCallEnd.alpha = if (canDisconnect) 1.0f else LOWER_ALPHA + itemConferenceCallEnd.setOnClickListener { + call.disconnect() + data.removeAt(position) + notifyItemRemoved(position) + if (data.size == 1) { + activity.finish() + } } - } - itemView.item_conference_call_end.setOnLongClickListener { - if (!it.contentDescription.isNullOrEmpty()) { - itemView.context.toast(it.contentDescription.toString()) + + itemConferenceCallEnd.setOnLongClickListener { + if (!it.contentDescription.isNullOrEmpty()) { + root.context.toast(it.contentDescription.toString()) + } + true } - true } } bindViewHolder(holder) @@ -96,7 +104,9 @@ class ConferenceCallsAdapter( override fun onViewRecycled(holder: ViewHolder) { super.onViewRecycled(holder) if (!activity.isDestroyed && !activity.isFinishing) { - Glide.with(activity).clear(holder.itemView.item_conference_call_image) + ItemConferenceCallBinding.bind(holder.itemView).apply { + Glide.with(activity).clear(itemConferenceCallImage) + } } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/ContactsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/ContactsAdapter.kt index 752a1501..4c689dda 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/ContactsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/ContactsAdapter.kt @@ -14,8 +14,11 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView +import androidx.viewbinding.ViewBinding import com.bumptech.glide.Glide import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter +import com.simplemobiletools.commons.databinding.ItemContactWithoutNumberBinding +import com.simplemobiletools.commons.databinding.ItemContactWithoutNumberGridBinding import com.simplemobiletools.commons.dialogs.ConfirmationDialog import com.simplemobiletools.commons.dialogs.FeatureLockedDialog import com.simplemobiletools.commons.extensions.* @@ -128,11 +131,8 @@ class ContactsAdapter( } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { - val layout = when (viewType) { - VIEW_TYPE_GRID -> R.layout.item_contact_without_number_grid - else -> R.layout.item_contact_without_number - } - return createViewHolder(layout, parent) + val binding = Binding.getByItemViewType(viewType).inflate(layoutInflater, parent, false) + return createViewHolder(binding.root) } override fun getItemViewType(position: Int): Int { @@ -142,7 +142,8 @@ class ContactsAdapter( override fun onBindViewHolder(holder: ViewHolder, position: Int) { val contact = contacts[position] holder.bindView(contact, true, allowLongClick) { itemView, layoutPosition -> - setupView(itemView, contact, holder) + val viewType = getItemViewType(position) + setupView(Binding.getByItemViewType(viewType).bind(itemView), contact, holder) } bindViewHolder(holder) } @@ -278,15 +279,17 @@ class ContactsAdapter( override fun onViewRecycled(holder: ViewHolder) { super.onViewRecycled(holder) if (!activity.isDestroyed && !activity.isFinishing) { - Glide.with(activity).clear(holder.itemView.findViewById(R.id.item_contact_image)) + Binding.getByItemViewType(holder.itemViewType).bind(holder.itemView).apply { + Glide.with(activity).clear(itemContactImage) + } } } - private fun setupView(view: View, contact: Contact, holder: ViewHolder) { - view.apply { - setupViewBackground(activity) - findViewById(R.id.item_contact_frame).isSelected = selectedKeys.contains(contact.rawId) - findViewById(R.id.item_contact_name).apply { + private fun setupView(binding: ItemViewBinding, contact: Contact, holder: ViewHolder) { + binding.apply { + root.setupViewBackground(activity) + itemContactFrame.isSelected = selectedKeys.contains(contact.rawId) + itemContactName.apply { setTextColor(textColor) setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize) @@ -300,9 +303,8 @@ class ContactsAdapter( } } - val dragIcon = findViewById(R.id.drag_handle_icon) if (enableDrag && textToHighlight.isEmpty()) { - dragIcon.apply { + dragHandleIcon.apply { beVisibleIf(selectedKeys.isNotEmpty()) applyColorFilter(textColor) setOnTouchListener { _, event -> @@ -313,14 +315,14 @@ class ContactsAdapter( } } } else { - dragIcon.apply { + dragHandleIcon.apply { beGone() setOnTouchListener(null) } } if (!activity.isDestroyed) { - SimpleContactsHelper(context).loadContactImage(contact.photoUri, findViewById(R.id.item_contact_image), contact.getNameToDisplay()) + SimpleContactsHelper(root.context).loadContactImage(contact.photoUri, itemContactImage, contact.getNameToDisplay()) } } } @@ -369,4 +371,63 @@ class ContactsAdapter( } } + private sealed interface Binding { + companion object { + fun getByItemViewType(viewType: Int): Binding { + return when (viewType) { + VIEW_TYPE_GRID -> ItemContactGrid + else -> ItemContact + } + } + } + + fun inflate(layoutInflater: LayoutInflater, viewGroup: ViewGroup, attachToRoot: Boolean): ItemViewBinding + + fun bind(view: View): ItemViewBinding + + data object ItemContactGrid : Binding { + override fun inflate(layoutInflater: LayoutInflater, viewGroup: ViewGroup, attachToRoot: Boolean): ItemViewBinding { + return ItemContactGridBindingAdapter(ItemContactWithoutNumberGridBinding.inflate(layoutInflater, viewGroup, attachToRoot)) + } + + override fun bind(view: View): ItemViewBinding { + return ItemContactGridBindingAdapter(ItemContactWithoutNumberGridBinding.bind(view)) + } + } + + data object ItemContact : Binding { + override fun inflate(layoutInflater: LayoutInflater, viewGroup: ViewGroup, attachToRoot: Boolean): ItemViewBinding { + return ItemContactBindingAdapter(ItemContactWithoutNumberBinding.inflate(layoutInflater, viewGroup, attachToRoot)) + } + + override fun bind(view: View): ItemViewBinding { + return ItemContactBindingAdapter(ItemContactWithoutNumberBinding.bind(view)) + } + } + } + + private interface ItemViewBinding : ViewBinding { + val itemContactName: TextView + val itemContactImage: ImageView + val itemContactFrame: ConstraintLayout + val dragHandleIcon: ImageView + } + + private class ItemContactGridBindingAdapter(val binding: ItemContactWithoutNumberGridBinding) : ItemViewBinding { + override val itemContactName = binding.itemContactName + override val itemContactImage = binding.itemContactImage + override val itemContactFrame = binding.itemContactFrame + override val dragHandleIcon = binding.dragHandleIcon + + override fun getRoot(): View = binding.root + } + + private class ItemContactBindingAdapter(val binding: ItemContactWithoutNumberBinding) : ItemViewBinding { + override val itemContactName = binding.itemContactName + override val itemContactImage = binding.itemContactImage + override val itemContactFrame = binding.itemContactFrame + override val dragHandleIcon = binding.dragHandleIcon + + override fun getRoot(): View = binding.root + } } diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/FilterContactSourcesAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/FilterContactSourcesAdapter.kt index 9a756857..7f245d7b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/FilterContactSourcesAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/FilterContactSourcesAdapter.kt @@ -8,9 +8,8 @@ import com.simplemobiletools.commons.extensions.getProperPrimaryColor import com.simplemobiletools.commons.extensions.getProperTextColor import com.simplemobiletools.commons.helpers.SMT_PRIVATE import com.simplemobiletools.commons.models.contacts.ContactSource -import com.simplemobiletools.dialer.R import com.simplemobiletools.dialer.activities.SimpleActivity -import kotlinx.android.synthetic.main.item_filter_contact_source.view.* +import com.simplemobiletools.dialer.databinding.ItemFilterContactSourceBinding class FilterContactSourcesAdapter( val activity: SimpleActivity, @@ -45,8 +44,8 @@ class FilterContactSourcesAdapter( fun getSelectedContactSources() = contactSources.filter { selectedKeys.contains(it.hashCode()) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { - val view = activity.layoutInflater.inflate(R.layout.item_filter_contact_source, parent, false) - return ViewHolder(view) + val binding = ItemFilterContactSourceBinding.inflate(activity.layoutInflater, parent, false) + return ViewHolder(binding.root) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { @@ -59,16 +58,16 @@ class FilterContactSourcesAdapter( inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { fun bindView(contactSource: ContactSource): View { val isSelected = selectedKeys.contains(contactSource.hashCode()) - itemView.apply { - filter_contact_source_checkbox.isChecked = isSelected - filter_contact_source_checkbox.setColors(activity.getProperTextColor(), activity.getProperPrimaryColor(), activity.getProperBackgroundColor()) + ItemFilterContactSourceBinding.bind(itemView).apply { + filterContactSourceCheckbox.isChecked = isSelected + filterContactSourceCheckbox.setColors(activity.getProperTextColor(), activity.getProperPrimaryColor(), activity.getProperBackgroundColor()) val countText = if (contactSource.count >= 0) " (${contactSource.count})" else "" val displayName = "${contactSource.publicName}$countText" - filter_contact_source_checkbox.text = displayName - filter_contact_source_holder.setOnClickListener { viewClicked(!isSelected, contactSource) } - } + filterContactSourceCheckbox.text = displayName + filterContactSourceHolder.setOnClickListener { viewClicked(!isSelected, contactSource) } - return itemView + return root + } } private fun viewClicked(select: Boolean, contactSource: ContactSource) { diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/RecentCallsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/RecentCallsAdapter.kt index 9735d400..6520c49d 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/RecentCallsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/RecentCallsAdapter.kt @@ -19,12 +19,12 @@ import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.dialer.R import com.simplemobiletools.dialer.activities.MainActivity import com.simplemobiletools.dialer.activities.SimpleActivity +import com.simplemobiletools.dialer.databinding.ItemRecentCallBinding import com.simplemobiletools.dialer.dialogs.ShowGroupedCallsDialog import com.simplemobiletools.dialer.extensions.* import com.simplemobiletools.dialer.helpers.RecentsHelper import com.simplemobiletools.dialer.interfaces.RefreshItemsListener import com.simplemobiletools.dialer.models.RecentCall -import kotlinx.android.synthetic.main.item_recent_call.view.* class RecentCallsAdapter( activity: SimpleActivity, @@ -103,7 +103,9 @@ class RecentCallsAdapter( override fun onActionModeDestroyed() {} - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_recent_call, parent) + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return createViewHolder(ItemRecentCallBinding.inflate(layoutInflater, parent, false).root) + } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val recentCall = recentCalls[position] @@ -112,7 +114,8 @@ class RecentCallsAdapter( allowSingleClick = refreshItemsListener != null && !recentCall.isUnknownNumber, allowLongClick = refreshItemsListener != null && !recentCall.isUnknownNumber ) { itemView, _ -> - setupView(itemView, recentCall) + val binding = ItemRecentCallBinding.bind(itemView) + setupView(binding, recentCall) } bindViewHolder(holder) } @@ -122,7 +125,9 @@ class RecentCallsAdapter( override fun onViewRecycled(holder: ViewHolder) { super.onViewRecycled(holder) if (!activity.isDestroyed && !activity.isFinishing) { - Glide.with(activity).clear(holder.itemView.item_recents_image) + ItemRecentCallBinding.bind(holder.itemView).apply { + Glide.with(activity).clear(itemRecentsImage) + } } } @@ -277,10 +282,10 @@ class RecentCallsAdapter( private fun getSelectedPhoneNumber() = getSelectedItems().firstOrNull()?.phoneNumber - private fun setupView(view: View, call: RecentCall) { - view.apply { + private fun setupView(binding: ItemRecentCallBinding, call: RecentCall) { + binding.apply { val currentFontSize = fontSize - item_recents_holder.isSelected = selectedKeys.contains(call.id) + itemRecentsHolder.isSelected = selectedKeys.contains(call.id) val name = findContactByCall(call)?.getNameToDisplay() ?: call.name var nameToShow = SpannableString(name) if (call.specificType.isNotEmpty()) { @@ -300,37 +305,37 @@ class RecentCallsAdapter( nameToShow = SpannableString(nameToShow.toString().highlightTextPart(textToHighlight, properPrimaryColor)) } - item_recents_name.apply { + itemRecentsName.apply { text = nameToShow setTextColor(textColor) setTextSize(TypedValue.COMPLEX_UNIT_PX, currentFontSize) } - item_recents_date_time.apply { + itemRecentsDateTime.apply { text = call.startTS.formatDateOrTime(context, refreshItemsListener != null, false) setTextColor(if (call.type == Calls.MISSED_TYPE) redColor else textColor) setTextSize(TypedValue.COMPLEX_UNIT_PX, currentFontSize * 0.8f) } - item_recents_duration.apply { + itemRecentsDuration.apply { text = call.duration.getFormattedDuration() setTextColor(textColor) beVisibleIf(call.type != Calls.MISSED_TYPE && call.type != Calls.REJECTED_TYPE && call.duration > 0) setTextSize(TypedValue.COMPLEX_UNIT_PX, currentFontSize * 0.8f) if (!showOverflowMenu) { - item_recents_duration.setPadding(0, 0, durationPadding, 0) + itemRecentsDuration.setPadding(0, 0, durationPadding, 0) } } - item_recents_sim_image.beVisibleIf(areMultipleSIMsAvailable && call.simID != -1) - item_recents_sim_id.beVisibleIf(areMultipleSIMsAvailable && call.simID != -1) + itemRecentsSimImage.beVisibleIf(areMultipleSIMsAvailable && call.simID != -1) + itemRecentsSimId.beVisibleIf(areMultipleSIMsAvailable && call.simID != -1) if (areMultipleSIMsAvailable && call.simID != -1) { - item_recents_sim_image.applyColorFilter(textColor) - item_recents_sim_id.setTextColor(textColor.getContrastColor()) - item_recents_sim_id.text = call.simID.toString() + itemRecentsSimImage.applyColorFilter(textColor) + itemRecentsSimId.setTextColor(textColor.getContrastColor()) + itemRecentsSimId.text = call.simID.toString() } - SimpleContactsHelper(context).loadContactImage(call.photoUri, item_recents_image, call.name) + SimpleContactsHelper(root.context).loadContactImage(call.photoUri, itemRecentsImage, call.name) val drawable = when (call.type) { Calls.OUTGOING_TYPE -> outgoingCallIcon @@ -338,15 +343,15 @@ class RecentCallsAdapter( else -> incomingCallIcon } - item_recents_type.setImageDrawable(drawable) + itemRecentsType.setImageDrawable(drawable) - overflow_menu_icon.beVisibleIf(showOverflowMenu) - overflow_menu_icon.drawable.apply { + overflowMenuIcon.beVisibleIf(showOverflowMenu) + overflowMenuIcon.drawable.apply { mutate() setTint(activity.getProperTextColor()) } - overflow_menu_icon.setOnClickListener { - showPopupMenu(overflow_menu_anchor, call) + overflowMenuIcon.setOnClickListener { + showPopupMenu(overflowMenuAnchor, call) } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/SpeedDialAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/SpeedDialAdapter.kt index a436d7e0..fb94d60e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/SpeedDialAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/SpeedDialAdapter.kt @@ -1,15 +1,14 @@ package com.simplemobiletools.dialer.adapters import android.view.Menu -import android.view.View import android.view.ViewGroup import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.dialer.R import com.simplemobiletools.dialer.activities.SimpleActivity +import com.simplemobiletools.dialer.databinding.ItemSpeedDialBinding import com.simplemobiletools.dialer.interfaces.RemoveSpeedDialListener import com.simplemobiletools.dialer.models.SpeedDial -import kotlinx.android.synthetic.main.item_speed_dial.view.speed_dial_label class SpeedDialAdapter( activity: SimpleActivity, var speedDialValues: List, private val removeListener: RemoveSpeedDialListener, @@ -45,12 +44,15 @@ class SpeedDialAdapter( override fun onActionModeDestroyed() {} - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_speed_dial, parent) + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return createViewHolder(ItemSpeedDialBinding.inflate(layoutInflater, parent, false).root) + } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val speedDial = speedDialValues[position] holder.bindView(speedDial, true, true) { itemView, layoutPosition -> - setupView(itemView, speedDial) + val binding = ItemSpeedDialBinding.bind(itemView) + setupView(binding, speedDial) } bindViewHolder(holder) } @@ -65,12 +67,12 @@ class SpeedDialAdapter( finishActMode() } - private fun setupView(view: View, speedDial: SpeedDial) { - view.apply { + private fun setupView(binding: ItemSpeedDialBinding, speedDial: SpeedDial) { + binding.apply { var displayName = "${speedDial.id}. " displayName += if (speedDial.isValid()) speedDial.displayName else "" - speed_dial_label.apply { + speedDialLabel.apply { text = displayName isSelected = selectedKeys.contains(speedDial.hashCode()) setTextColor(textColor) diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/ViewPagerAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/ViewPagerAdapter.kt index 60a8ceb6..2aa55696 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/ViewPagerAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/adapters/ViewPagerAdapter.kt @@ -19,7 +19,7 @@ class ViewPagerAdapter(val activity: SimpleActivity) : PagerAdapter() { val view = activity.layoutInflater.inflate(layout, container, false) container.addView(view) - (view as MyViewPagerFragment).apply { + (view as MyViewPagerFragment<*>).apply { setupFragment(activity) } diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/ChangeSortingDialog.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/ChangeSortingDialog.kt index db411f26..6f518f6c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/ChangeSortingDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/ChangeSortingDialog.kt @@ -4,22 +4,24 @@ import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.extensions.beGoneIf import com.simplemobiletools.commons.extensions.getAlertDialogBuilder import com.simplemobiletools.commons.extensions.setupDialogStuff +import com.simplemobiletools.commons.extensions.viewBinding import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.dialer.R +import com.simplemobiletools.dialer.databinding.DialogChangeSortingBinding import com.simplemobiletools.dialer.extensions.config -import kotlinx.android.synthetic.main.dialog_change_sorting.view.* class ChangeSortingDialog(val activity: BaseSimpleActivity, private val showCustomSorting: Boolean = false, private val callback: () -> Unit) { + private val binding by activity.viewBinding(DialogChangeSortingBinding::inflate) + private var currSorting = 0 private var config = activity.config - private var view = activity.layoutInflater.inflate(R.layout.dialog_change_sorting, null) init { activity.getAlertDialogBuilder() .setPositiveButton(R.string.ok) { dialog, which -> dialogConfirmed() } .setNegativeButton(R.string.cancel, null) .apply { - activity.setupDialogStuff(view, this, R.string.sort_by) + activity.setupDialogStuff(binding.root, this, R.string.sort_by) } currSorting = if (showCustomSorting && config.isCustomOrderSelected) { @@ -33,43 +35,41 @@ class ChangeSortingDialog(val activity: BaseSimpleActivity, private val showCust } private fun setupSortRadio() { - val sortingRadio = view.sorting_dialog_radio_sorting + binding.apply { + sortingDialogRadioSorting.setOnCheckedChangeListener { group, checkedId -> + val isCustomSorting = checkedId == sortingDialogRadioCustom.id + sortingDialogRadioOrder.beGoneIf(isCustomSorting) + divider.beGoneIf(isCustomSorting) + } - sortingRadio.setOnCheckedChangeListener { group, checkedId -> - val isCustomSorting = checkedId == sortingRadio.sorting_dialog_radio_custom.id - view.sorting_dialog_radio_order.beGoneIf(isCustomSorting) - view.divider.beGoneIf(isCustomSorting) - } + val sortBtn = when { + currSorting and SORT_BY_FIRST_NAME != 0 -> sortingDialogRadioFirstName + currSorting and SORT_BY_MIDDLE_NAME != 0 -> sortingDialogRadioMiddleName + currSorting and SORT_BY_SURNAME != 0 -> sortingDialogRadioSurname + currSorting and SORT_BY_FULL_NAME != 0 -> sortingDialogRadioFullName + currSorting and SORT_BY_CUSTOM != 0 -> sortingDialogRadioCustom + else -> sortingDialogRadioDateCreated + } + sortBtn.isChecked = true - val sortBtn = when { - currSorting and SORT_BY_FIRST_NAME != 0 -> sortingRadio.sorting_dialog_radio_first_name - currSorting and SORT_BY_MIDDLE_NAME != 0 -> sortingRadio.sorting_dialog_radio_middle_name - currSorting and SORT_BY_SURNAME != 0 -> sortingRadio.sorting_dialog_radio_surname - currSorting and SORT_BY_FULL_NAME != 0 -> sortingRadio.sorting_dialog_radio_full_name - currSorting and SORT_BY_CUSTOM != 0 -> sortingRadio.sorting_dialog_radio_custom - else -> sortingRadio.sorting_dialog_radio_date_created + if (showCustomSorting) { + sortingDialogRadioCustom.isChecked = config.isCustomOrderSelected + } + sortingDialogRadioCustom.beGoneIf(!showCustomSorting) } - sortBtn.isChecked = true - - if (showCustomSorting) { - sortingRadio.sorting_dialog_radio_custom.isChecked = config.isCustomOrderSelected - } - view.sorting_dialog_radio_custom.beGoneIf(!showCustomSorting) } private fun setupOrderRadio() { - val orderRadio = view.sorting_dialog_radio_order - var orderBtn = orderRadio.sorting_dialog_radio_ascending - + var orderBtn = binding.sortingDialogRadioAscending if (currSorting and SORT_DESCENDING != 0) { - orderBtn = orderRadio.sorting_dialog_radio_descending + orderBtn = binding.sortingDialogRadioDescending } + orderBtn.isChecked = true } private fun dialogConfirmed() { - val sortingRadio = view.sorting_dialog_radio_sorting - var sorting = when (sortingRadio.checkedRadioButtonId) { + var sorting = when (binding.sortingDialogRadioSorting.checkedRadioButtonId) { R.id.sorting_dialog_radio_first_name -> SORT_BY_FIRST_NAME R.id.sorting_dialog_radio_middle_name -> SORT_BY_MIDDLE_NAME R.id.sorting_dialog_radio_surname -> SORT_BY_SURNAME @@ -78,7 +78,7 @@ class ChangeSortingDialog(val activity: BaseSimpleActivity, private val showCust else -> SORT_BY_DATE_CREATED } - if (sorting != SORT_BY_CUSTOM && view.sorting_dialog_radio_order.checkedRadioButtonId == R.id.sorting_dialog_radio_descending) { + if (sorting != SORT_BY_CUSTOM && binding.sortingDialogRadioOrder.checkedRadioButtonId == R.id.sorting_dialog_radio_descending) { sorting = sorting or SORT_DESCENDING } diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/DynamicBottomSheetChooserDialog.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/DynamicBottomSheetChooserDialog.kt index eebe3ae1..fa54012e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/DynamicBottomSheetChooserDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/DynamicBottomSheetChooserDialog.kt @@ -6,17 +6,17 @@ import androidx.fragment.app.FragmentManager import com.simplemobiletools.commons.adapters.SimpleListItemAdapter import com.simplemobiletools.commons.fragments.BaseBottomSheetDialogFragment import com.simplemobiletools.commons.models.SimpleListItem -import com.simplemobiletools.dialer.R -import kotlinx.android.synthetic.main.layout_simple_recycler_view.* +import com.simplemobiletools.dialer.databinding.LayoutSimpleRecyclerViewBinding // same as BottomSheetChooserDialog but with dynamic updates class DynamicBottomSheetChooserDialog : BaseBottomSheetDialogFragment() { + private lateinit var binding: LayoutSimpleRecyclerViewBinding var onItemClick: ((SimpleListItem) -> Unit)? = null override fun setupContentView(parent: ViewGroup) { - val child = layoutInflater.inflate(R.layout.layout_simple_recycler_view, parent, false) - parent.addView(child) + binding = LayoutSimpleRecyclerViewBinding.inflate(layoutInflater, parent, false) + parent.addView(binding.root) setupRecyclerView() } @@ -27,13 +27,13 @@ class DynamicBottomSheetChooserDialog : BaseBottomSheetDialogFragment() { } private fun getRecyclerViewAdapter(): SimpleListItemAdapter { - var adapter = recycler_view.adapter as? SimpleListItemAdapter + var adapter = binding.recyclerView.adapter as? SimpleListItemAdapter if (adapter == null) { adapter = SimpleListItemAdapter(requireActivity()) { onItemClick?.invoke(it) dismissAllowingStateLoss() } - recycler_view.adapter = adapter + binding.recyclerView.adapter = adapter } return adapter } diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/ExportCallHistoryDialog.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/ExportCallHistoryDialog.kt index e989ee57..48dfed53 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/ExportCallHistoryDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/ExportCallHistoryDialog.kt @@ -1,24 +1,23 @@ package com.simplemobiletools.dialer.dialogs -import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.dialer.R import com.simplemobiletools.dialer.activities.SimpleActivity -import kotlinx.android.synthetic.main.dialog_export_call_history.view.export_call_history_filename +import com.simplemobiletools.dialer.databinding.DialogExportCallHistoryBinding class ExportCallHistoryDialog(val activity: SimpleActivity, callback: (filename: String) -> Unit) { init { - val view = (activity.layoutInflater.inflate(R.layout.dialog_export_call_history, null) as ViewGroup).apply { - export_call_history_filename.setText("call_history_${activity.getCurrentFormattedDateTime()}") + val binding = DialogExportCallHistoryBinding.inflate(activity.layoutInflater).apply { + exportCallHistoryFilename.setText("call_history_${activity.getCurrentFormattedDateTime()}") } activity.getAlertDialogBuilder().setPositiveButton(R.string.ok, null).setNegativeButton(R.string.cancel, null).apply { - activity.setupDialogStuff(view, this, R.string.export_call_history) { alertDialog -> + activity.setupDialogStuff(binding.root, this, R.string.export_call_history) { alertDialog -> alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { - val filename = view.export_call_history_filename.value + val filename = binding.exportCallHistoryFilename.value when { filename.isEmpty() -> activity.toast(R.string.empty_name) filename.isAValidFilename() -> { diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/FilterContactSourcesDialog.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/FilterContactSourcesDialog.kt index 5ff44d7a..9728824e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/FilterContactSourcesDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/FilterContactSourcesDialog.kt @@ -1,31 +1,30 @@ package com.simplemobiletools.dialer.dialogs import androidx.appcompat.app.AlertDialog -import com.simplemobiletools.commons.extensions.getAlertDialogBuilder -import com.simplemobiletools.commons.extensions.getMyContactsCursor -import com.simplemobiletools.commons.extensions.setupDialogStuff -import com.simplemobiletools.commons.helpers.SMT_PRIVATE -import com.simplemobiletools.commons.extensions.getVisibleContactSources +import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.ContactsHelper import com.simplemobiletools.commons.helpers.MyContactsContentProvider -import com.simplemobiletools.commons.models.contacts.* +import com.simplemobiletools.commons.helpers.SMT_PRIVATE +import com.simplemobiletools.commons.models.contacts.Contact +import com.simplemobiletools.commons.models.contacts.ContactSource import com.simplemobiletools.dialer.R import com.simplemobiletools.dialer.activities.SimpleActivity import com.simplemobiletools.dialer.adapters.FilterContactSourcesAdapter +import com.simplemobiletools.dialer.databinding.DialogFilterContactSourcesBinding import com.simplemobiletools.dialer.extensions.config -import kotlinx.android.synthetic.main.dialog_filter_contact_sources.view.* class FilterContactSourcesDialog(val activity: SimpleActivity, private val callback: () -> Unit) { + private val binding by activity.viewBinding(DialogFilterContactSourcesBinding::inflate) + private var dialog: AlertDialog? = null - private val view = activity.layoutInflater.inflate(R.layout.dialog_filter_contact_sources, null) private var contactSources = ArrayList() private var contacts = ArrayList() private var isContactSourcesReady = false private var isContactsReady = false init { - val contactHelper = ContactsHelper(activity) - contactHelper.getContactSources { contactSources -> + val contactHelper = ContactsHelper(activity) + contactHelper.getContactSources { contactSources -> contactSources.mapTo(this@FilterContactSourcesDialog.contactSources) { it.copy() } isContactSourcesReady = true processDataIfReady() @@ -61,14 +60,14 @@ class FilterContactSourcesDialog(val activity: SimpleActivity, private val callb activity.runOnUiThread { val selectedSources = activity.getVisibleContactSources() - view.filter_contact_sources_list.adapter = FilterContactSourcesAdapter(activity, contactSourcesWithCount, selectedSources) + binding.filterContactSourcesList.adapter = FilterContactSourcesAdapter(activity, contactSourcesWithCount, selectedSources) if (dialog == null) { activity.getAlertDialogBuilder() .setPositiveButton(R.string.ok) { dialogInterface, i -> confirmContactSources() } .setNegativeButton(R.string.cancel, null) .apply { - activity.setupDialogStuff(view, this) { alertDialog -> + activity.setupDialogStuff(binding.root, this) { alertDialog -> dialog = alertDialog } } @@ -77,7 +76,7 @@ class FilterContactSourcesDialog(val activity: SimpleActivity, private val callb } private fun confirmContactSources() { - val selectedContactSources = (view.filter_contact_sources_list.adapter as FilterContactSourcesAdapter).getSelectedContactSources() + val selectedContactSources = (binding.filterContactSourcesList.adapter as FilterContactSourcesAdapter).getSelectedContactSources() val ignoredContactSources = contactSources.filter { !selectedContactSources.contains(it) }.map { if (it.type == SMT_PRIVATE) SMT_PRIVATE else it.getFullIdentifier() }.toHashSet() diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/ManageVisibleTabsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/ManageVisibleTabsDialog.kt index 3b4c5d52..b1ccf2a4 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/ManageVisibleTabsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/ManageVisibleTabsDialog.kt @@ -3,16 +3,18 @@ package com.simplemobiletools.dialer.dialogs import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.extensions.getAlertDialogBuilder import com.simplemobiletools.commons.extensions.setupDialogStuff +import com.simplemobiletools.commons.extensions.viewBinding import com.simplemobiletools.commons.helpers.TAB_CALL_HISTORY import com.simplemobiletools.commons.helpers.TAB_CONTACTS import com.simplemobiletools.commons.helpers.TAB_FAVORITES import com.simplemobiletools.commons.views.MyAppCompatCheckbox import com.simplemobiletools.dialer.R +import com.simplemobiletools.dialer.databinding.DialogManageVisibleTabsBinding import com.simplemobiletools.dialer.extensions.config import com.simplemobiletools.dialer.helpers.ALL_TABS_MASK class ManageVisibleTabsDialog(val activity: BaseSimpleActivity) { - private var view = activity.layoutInflater.inflate(R.layout.dialog_manage_visible_tabs, null) + private val binding by activity.viewBinding(DialogManageVisibleTabsBinding::inflate) private val tabs = LinkedHashMap() init { @@ -24,21 +26,21 @@ class ManageVisibleTabsDialog(val activity: BaseSimpleActivity) { val showTabs = activity.config.showTabs for ((key, value) in tabs) { - view.findViewById(value).isChecked = showTabs and key != 0 + binding.root.findViewById(value).isChecked = showTabs and key != 0 } activity.getAlertDialogBuilder() .setPositiveButton(R.string.ok) { dialog, which -> dialogConfirmed() } .setNegativeButton(R.string.cancel, null) .apply { - activity.setupDialogStuff(view, this) + activity.setupDialogStuff(binding.root, this) } } private fun dialogConfirmed() { var result = 0 for ((key, value) in tabs) { - if (view.findViewById(value).isChecked) { + if (binding.root.findViewById(value).isChecked) { result += key } } diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/SelectContactDialog.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/SelectContactDialog.kt index b69f385a..20c87fab 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/SelectContactDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/SelectContactDialog.kt @@ -2,9 +2,7 @@ package com.simplemobiletools.dialer.dialogs import android.graphics.Color import android.view.KeyEvent -import android.view.View import android.view.inputmethod.EditorInfo -import android.widget.EditText import android.widget.ImageView import androidx.appcompat.app.AlertDialog import com.reddit.indicatorfastscroll.FastScrollItemIndicator @@ -14,27 +12,25 @@ import com.simplemobiletools.commons.views.MySearchMenu import com.simplemobiletools.dialer.R import com.simplemobiletools.dialer.activities.SimpleActivity import com.simplemobiletools.dialer.adapters.ContactsAdapter -import kotlinx.android.synthetic.main.dialog_select_contact.view.* +import com.simplemobiletools.dialer.databinding.DialogSelectContactBinding import java.util.Locale class SelectContactDialog(val activity: SimpleActivity, val contacts: List, val callback: (selectedContact: Contact) -> Unit) { + private val binding by activity.viewBinding(DialogSelectContactBinding::inflate) + private var dialog: AlertDialog? = null - private var view = activity.layoutInflater.inflate(R.layout.dialog_select_contact, null) - private val searchView = view.contact_search_view - private val searchEditText = view.findViewById(R.id.top_toolbar_search) - private val searchViewAppBarLayout = view.findViewById(R.id.top_app_bar_layout) init { - view.apply { - letter_fastscroller.textColor = context.getProperTextColor().getColorStateList() - letter_fastscroller_thumb.setupWithFastScroller(letter_fastscroller) - letter_fastscroller_thumb.textColor = context.getProperPrimaryColor().getContrastColor() - letter_fastscroller_thumb.thumbColor = context.getProperPrimaryColor().getColorStateList() + binding.apply { + letterFastscroller.textColor = activity.getProperTextColor().getColorStateList() + letterFastscrollerThumb.setupWithFastScroller(letterFastscroller) + letterFastscrollerThumb.textColor = activity.getProperPrimaryColor().getContrastColor() + letterFastscrollerThumb.thumbColor = activity.getProperPrimaryColor().getColorStateList() setupLetterFastScroller(contacts) configureSearchView() - select_contact_list.adapter = ContactsAdapter(activity, contacts.toMutableList(), select_contact_list, allowLongClick = false) { + selectContactList.adapter = ContactsAdapter(activity, contacts.toMutableList(), selectContactList, allowLongClick = false) { callback(it as Contact) dialog?.dismiss() } @@ -49,14 +45,14 @@ class SelectContactDialog(val activity: SimpleActivity, val contacts: List + activity.setupDialogStuff(binding.root, this, R.string.choose_contact) { alertDialog -> dialog = alertDialog } } } private fun setupLetterFastScroller(contacts: List) { - view.letter_fastscroller.setupWithRecyclerView(view.select_contact_list, { position -> + binding.letterFastscroller.setupWithRecyclerView(binding.selectContactList, { position -> try { val name = contacts[position].getNameToDisplay() val character = if (name.isNotEmpty()) name.substring(0, 1) else "" @@ -67,9 +63,9 @@ class SelectContactDialog(val activity: SimpleActivity, val contacts: List(R.id.top_toolbar_search_icon)) { + private fun updateSearchViewLeftIcon(iconResId: Int) = with(binding.root.findViewById(R.id.top_toolbar_search_icon)) { post { setImageResource(iconResId) } } private fun filterContactListBySearchQuery(query: String) { - val adapter = view.select_contact_list.adapter as? ContactsAdapter + val adapter = binding.selectContactList.adapter as? ContactsAdapter var contactsToShow = contacts if (query.isNotEmpty()) { contactsToShow = contacts.filter { it.name.contains(query, true) } @@ -117,7 +113,7 @@ class SelectContactDialog(val activity: SimpleActivity, val contacts: List) = with(view) { - contacts_empty_placeholder.beVisibleIf(contacts.isEmpty()) + private fun checkPlaceholderVisibility(contacts: List) = with(binding) { + contactsEmptyPlaceholder.beVisibleIf(contacts.isEmpty()) - if (contact_search_view.isSearchOpen) { - contacts_empty_placeholder.text = context.getString(R.string.no_items_found) + if (contactSearchView.isSearchOpen) { + contactsEmptyPlaceholder.text = activity.getString(R.string.no_items_found) } - letter_fastscroller.beVisibleIf(contacts_empty_placeholder.isGone()) - letter_fastscroller_thumb.beVisibleIf(contacts_empty_placeholder.isGone()) + letterFastscroller.beVisibleIf(contactsEmptyPlaceholder.isGone()) + letterFastscrollerThumb.beVisibleIf(contactsEmptyPlaceholder.isGone()) } private fun backPressed() { - if (searchView.isSearchOpen) { - searchView.closeSearch() + if (binding.contactSearchView.isSearchOpen) { + binding.contactSearchView.closeSearch() } else { dialog?.dismiss() } diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/SelectSIMDialog.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/SelectSIMDialog.kt index da6d85ad..a1443b7f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/SelectSIMDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/SelectSIMDialog.kt @@ -9,10 +9,11 @@ import androidx.appcompat.app.AlertDialog import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.extensions.getAlertDialogBuilder import com.simplemobiletools.commons.extensions.setupDialogStuff +import com.simplemobiletools.commons.extensions.viewBinding import com.simplemobiletools.dialer.R +import com.simplemobiletools.dialer.databinding.DialogSelectSimBinding import com.simplemobiletools.dialer.extensions.config import com.simplemobiletools.dialer.extensions.getAvailableSIMCardLabels -import kotlinx.android.synthetic.main.dialog_select_sim.view.* @SuppressLint("MissingPermission") class SelectSIMDialog( @@ -22,14 +23,11 @@ class SelectSIMDialog( val callback: (handle: PhoneAccountHandle?) -> Unit ) { private var dialog: AlertDialog? = null - private val view = activity.layoutInflater.inflate(R.layout.dialog_select_sim, null) + private val binding by activity.viewBinding(DialogSelectSimBinding::inflate) init { - val radioGroup = view.select_sim_radio_group - view.apply { - select_sim_remember_holder.setOnClickListener { - select_sim_remember.toggle() - } + binding.selectSimRememberHolder.setOnClickListener { + binding.selectSimRemember.toggle() } activity.getAvailableSIMCardLabels().forEachIndexed { index, SIMAccount -> @@ -38,12 +36,12 @@ class SelectSIMDialog( id = index setOnClickListener { selectedSIM(SIMAccount.handle) } } - radioGroup!!.addView(radioButton, RadioGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)) + binding.selectSimRadioGroup.addView(radioButton, RadioGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)) } activity.getAlertDialogBuilder() .apply { - activity.setupDialogStuff(view, this) { alertDialog -> + activity.setupDialogStuff(binding.root, this) { alertDialog -> dialog = alertDialog } } @@ -54,7 +52,7 @@ class SelectSIMDialog( } private fun selectedSIM(handle: PhoneAccountHandle) { - if (view.select_sim_remember.isChecked) { + if (binding.selectSimRemember.isChecked) { activity.config.saveCustomSIM(phoneNumber, handle) } diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/ShowGroupedCallsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/ShowGroupedCallsDialog.kt index e369a009..ceef9ee1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/ShowGroupedCallsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/dialogs/ShowGroupedCallsDialog.kt @@ -4,33 +4,31 @@ import androidx.appcompat.app.AlertDialog import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.extensions.getAlertDialogBuilder import com.simplemobiletools.commons.extensions.setupDialogStuff -import com.simplemobiletools.dialer.R +import com.simplemobiletools.commons.extensions.viewBinding import com.simplemobiletools.dialer.activities.SimpleActivity import com.simplemobiletools.dialer.adapters.RecentCallsAdapter +import com.simplemobiletools.dialer.databinding.DialogShowGroupedCallsBinding import com.simplemobiletools.dialer.helpers.RecentsHelper import com.simplemobiletools.dialer.models.RecentCall -import kotlinx.android.synthetic.main.dialog_show_grouped_calls.view.* class ShowGroupedCallsDialog(val activity: BaseSimpleActivity, callIds: ArrayList) { private var dialog: AlertDialog? = null - private var view = activity.layoutInflater.inflate(R.layout.dialog_show_grouped_calls, null) + private val binding by activity.viewBinding(DialogShowGroupedCallsBinding::inflate) init { - view.apply { - RecentsHelper(activity).getRecentCalls(false) { allRecents -> - val recents = allRecents.filter { callIds.contains(it.id) }.toMutableList() as ArrayList - activity.runOnUiThread { - RecentCallsAdapter(activity as SimpleActivity, recents, select_grouped_calls_list, null, false) { - }.apply { - select_grouped_calls_list.adapter = this - } + RecentsHelper(activity).getRecentCalls(false) { allRecents -> + val recents = allRecents.filter { callIds.contains(it.id) }.toMutableList() as ArrayList + activity.runOnUiThread { + RecentCallsAdapter(activity as SimpleActivity, recents, binding.selectGroupedCallsList, null, false) { + }.apply { + binding.selectGroupedCallsList.adapter = this } } } activity.getAlertDialogBuilder() .apply { - activity.setupDialogStuff(view, this) { alertDialog -> + activity.setupDialogStuff(binding.root, this) { alertDialog -> dialog = alertDialog } } diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/fragments/ContactsFragment.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/fragments/ContactsFragment.kt index de4d3bb3..cb15843e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/fragments/ContactsFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/fragments/ContactsFragment.kt @@ -11,15 +11,24 @@ import com.simplemobiletools.dialer.R import com.simplemobiletools.dialer.activities.MainActivity import com.simplemobiletools.dialer.activities.SimpleActivity import com.simplemobiletools.dialer.adapters.ContactsAdapter +import com.simplemobiletools.dialer.databinding.FragmentContactsBinding +import com.simplemobiletools.dialer.databinding.FragmentLettersLayoutBinding import com.simplemobiletools.dialer.extensions.launchCreateNewContactIntent import com.simplemobiletools.dialer.extensions.startContactDetailsIntent import com.simplemobiletools.dialer.interfaces.RefreshItemsListener -import kotlinx.android.synthetic.main.fragment_letters_layout.view.* import java.util.Locale -class ContactsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet), RefreshItemsListener { +class ContactsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet), + RefreshItemsListener { + private lateinit var binding: FragmentLettersLayoutBinding private var allContacts = ArrayList() + override fun onFinishInflate() { + super.onFinishInflate() + binding = FragmentLettersLayoutBinding.bind(FragmentContactsBinding.bind(this).contactsFragment) + innerBinding = LettersInnerBinding(binding) + } + override fun setupFragment() { val placeholderResId = if (context.hasPermission(PERMISSION_READ_CONTACTS)) { R.string.no_contacts_found @@ -27,7 +36,7 @@ class ContactsFragment(context: Context, attributeSet: AttributeSet) : MyViewPag R.string.could_not_access_contacts } - fragment_placeholder.text = context.getString(placeholderResId) + binding.fragmentPlaceholder.text = context.getString(placeholderResId) val placeholderActionResId = if (context.hasPermission(PERMISSION_READ_CONTACTS)) { R.string.create_new_contact @@ -35,7 +44,7 @@ class ContactsFragment(context: Context, attributeSet: AttributeSet) : MyViewPag R.string.request_access } - fragment_placeholder_2.apply { + binding.fragmentPlaceholder2.apply { text = context.getString(placeholderActionResId) underlineText() setOnClickListener { @@ -49,15 +58,17 @@ class ContactsFragment(context: Context, attributeSet: AttributeSet) : MyViewPag } override fun setupColors(textColor: Int, primaryColor: Int, properPrimaryColor: Int) { - (fragment_list?.adapter as? MyRecyclerViewAdapter)?.updateTextColor(textColor) - fragment_placeholder.setTextColor(textColor) - fragment_placeholder_2.setTextColor(properPrimaryColor) + binding.apply { + (fragmentList?.adapter as? MyRecyclerViewAdapter)?.updateTextColor(textColor) + fragmentPlaceholder.setTextColor(textColor) + fragmentPlaceholder2.setTextColor(properPrimaryColor) - letter_fastscroller.textColor = textColor.getColorStateList() - letter_fastscroller.pressedTextColor = properPrimaryColor - letter_fastscroller_thumb.setupWithFastScroller(letter_fastscroller) - letter_fastscroller_thumb.textColor = properPrimaryColor.getContrastColor() - letter_fastscroller_thumb.thumbColor = properPrimaryColor.getColorStateList() + letterFastscroller.textColor = textColor.getColorStateList() + letterFastscroller.pressedTextColor = properPrimaryColor + letterFastscrollerThumb.setupWithFastScroller(letterFastscroller) + letterFastscrollerThumb.textColor = properPrimaryColor.getContrastColor() + letterFastscrollerThumb.thumbColor = properPrimaryColor.getColorStateList() + } } override fun refreshItems(callback: (() -> Unit)?) { @@ -84,39 +95,42 @@ class ContactsFragment(context: Context, attributeSet: AttributeSet) : MyViewPag private fun gotContacts(contacts: ArrayList) { setupLetterFastScroller(contacts) if (contacts.isEmpty()) { - fragment_placeholder.beVisible() - fragment_placeholder_2.beVisible() - fragment_list.beGone() + binding.apply { + fragmentPlaceholder.beVisible() + fragmentPlaceholder2.beVisible() + fragmentList.beGone() + } } else { - fragment_placeholder.beGone() - fragment_placeholder_2.beGone() - fragment_list.beVisible() + binding.apply { + fragmentPlaceholder.beGone() + fragmentPlaceholder2.beGone() + fragmentList.beVisible() + } - val currAdapter = fragment_list.adapter - if (currAdapter == null) { + if (binding.fragmentList.adapter == null) { ContactsAdapter( activity = activity as SimpleActivity, contacts = contacts, - recyclerView = fragment_list, + recyclerView = binding.fragmentList, refreshItemsListener = this ) { val contact = it as Contact activity?.startContactDetailsIntent(contact) }.apply { - fragment_list.adapter = this + binding.fragmentList.adapter = this } if (context.areSystemAnimationsEnabled) { - fragment_list.scheduleLayoutAnimation() + binding.fragmentList.scheduleLayoutAnimation() } } else { - (currAdapter as ContactsAdapter).updateItems(contacts) + (binding.fragmentList.adapter as ContactsAdapter).updateItems(contacts) } } } private fun setupLetterFastScroller(contacts: ArrayList) { - letter_fastscroller.setupWithRecyclerView(fragment_list, { position -> + binding.letterFastscroller.setupWithRecyclerView(binding.fragmentList, { position -> try { val name = contacts[position].getNameToDisplay() val character = if (name.isNotEmpty()) name.substring(0, 1) else "" @@ -128,8 +142,8 @@ class ContactsFragment(context: Context, attributeSet: AttributeSet) : MyViewPag } override fun onSearchClosed() { - fragment_placeholder.beVisibleIf(allContacts.isEmpty()) - (fragment_list.adapter as? ContactsAdapter)?.updateItems(allContacts) + binding.fragmentPlaceholder.beVisibleIf(allContacts.isEmpty()) + (binding.fragmentList.adapter as? ContactsAdapter)?.updateItems(allContacts) setupLetterFastScroller(allContacts) } @@ -155,16 +169,16 @@ class ContactsFragment(context: Context, attributeSet: AttributeSet) : MyViewPag !getProperText(nameToDisplay, shouldNormalize).startsWith(text, true) && !nameToDisplay.contains(text, true) } - fragment_placeholder.beVisibleIf(filtered.isEmpty()) - (fragment_list.adapter as? ContactsAdapter)?.updateItems(filtered, text) + binding.fragmentPlaceholder.beVisibleIf(filtered.isEmpty()) + (binding.fragmentList.adapter as? ContactsAdapter)?.updateItems(filtered, text) setupLetterFastScroller(filtered) } private fun requestReadContactsPermission() { activity?.handlePermission(PERMISSION_READ_CONTACTS) { if (it) { - fragment_placeholder.text = context.getString(R.string.no_contacts_found) - fragment_placeholder_2.text = context.getString(R.string.create_new_contact) + binding.fragmentPlaceholder.text = context.getString(R.string.no_contacts_found) + binding.fragmentPlaceholder2.text = context.getString(R.string.create_new_contact) ContactsHelper(context).getContacts(showOnlyContactsWithNumbers = true) { contacts -> activity?.runOnUiThread { gotContacts(contacts) diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/fragments/FavoritesFragment.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/fragments/FavoritesFragment.kt index 794438fd..5a41181c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/fragments/FavoritesFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/fragments/FavoritesFragment.kt @@ -14,15 +14,24 @@ import com.simplemobiletools.commons.views.MyLinearLayoutManager import com.simplemobiletools.dialer.R import com.simplemobiletools.dialer.activities.SimpleActivity import com.simplemobiletools.dialer.adapters.ContactsAdapter +import com.simplemobiletools.dialer.databinding.FragmentFavoritesBinding +import com.simplemobiletools.dialer.databinding.FragmentLettersLayoutBinding import com.simplemobiletools.dialer.extensions.config import com.simplemobiletools.dialer.helpers.Converters import com.simplemobiletools.dialer.interfaces.RefreshItemsListener -import kotlinx.android.synthetic.main.fragment_letters_layout.view.* import java.util.Locale -class FavoritesFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet), RefreshItemsListener { +class FavoritesFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet), + RefreshItemsListener { + private lateinit var binding: FragmentLettersLayoutBinding private var allContacts = ArrayList() + override fun onFinishInflate() { + super.onFinishInflate() + binding = FragmentLettersLayoutBinding.bind(FragmentFavoritesBinding.bind(this).favoritesFragment) + innerBinding = LettersInnerBinding(binding) + } + override fun setupFragment() { val placeholderResId = if (context.hasPermission(PERMISSION_READ_CONTACTS)) { R.string.no_contacts_found @@ -30,19 +39,21 @@ class FavoritesFragment(context: Context, attributeSet: AttributeSet) : MyViewPa R.string.could_not_access_contacts } - fragment_placeholder.text = context.getString(placeholderResId) - fragment_placeholder_2.beGone() + binding.fragmentPlaceholder.text = context.getString(placeholderResId) + binding.fragmentPlaceholder2.beGone() } override fun setupColors(textColor: Int, primaryColor: Int, properPrimaryColor: Int) { - fragment_placeholder.setTextColor(textColor) - (fragment_list?.adapter as? MyRecyclerViewAdapter)?.updateTextColor(textColor) + binding.apply { + fragmentPlaceholder.setTextColor(textColor) + (fragmentList.adapter as? MyRecyclerViewAdapter)?.updateTextColor(textColor) - letter_fastscroller.textColor = textColor.getColorStateList() - letter_fastscroller.pressedTextColor = properPrimaryColor - letter_fastscroller_thumb.setupWithFastScroller(letter_fastscroller) - letter_fastscroller_thumb.textColor = properPrimaryColor.getContrastColor() - letter_fastscroller_thumb.thumbColor = properPrimaryColor.getColorStateList() + letterFastscroller.textColor = textColor.getColorStateList() + letterFastscroller.pressedTextColor = properPrimaryColor + letterFastscrollerThumb.setupWithFastScroller(letterFastscroller) + letterFastscrollerThumb.textColor = properPrimaryColor.getContrastColor() + letterFastscrollerThumb.thumbColor = properPrimaryColor.getColorStateList() + } } override fun refreshItems(callback: (() -> Unit)?) { @@ -76,14 +87,16 @@ class FavoritesFragment(context: Context, attributeSet: AttributeSet) : MyViewPa private fun gotContacts(contacts: ArrayList) { setupLetterFastScroller(contacts) - if (contacts.isEmpty()) { - fragment_placeholder.beVisible() - fragment_list.beGone() - } else { - fragment_placeholder.beGone() - fragment_list.beVisible() + binding.apply { + if (contacts.isEmpty()) { + fragmentPlaceholder.beVisible() + fragmentList.beGone() + } else { + fragmentPlaceholder.beGone() + fragmentList.beVisible() - updateListAdapter() + updateListAdapter() + } } } @@ -91,12 +104,12 @@ class FavoritesFragment(context: Context, attributeSet: AttributeSet) : MyViewPa val viewType = context.config.viewType setViewType(viewType) - val currAdapter = fragment_list.adapter as ContactsAdapter? + val currAdapter = binding.fragmentList.adapter as ContactsAdapter? if (currAdapter == null) { ContactsAdapter( activity = activity as SimpleActivity, contacts = allContacts, - recyclerView = fragment_list, + recyclerView = binding.fragmentList, refreshItemsListener = this, viewType = viewType, showDeleteButton = false, @@ -114,10 +127,10 @@ class FavoritesFragment(context: Context, attributeSet: AttributeSet) : MyViewPa } } }.apply { - fragment_list.adapter = this + binding.fragmentList.adapter = this onDragEndListener = { - val adapter = fragment_list?.adapter + val adapter = binding.fragmentList.adapter if (adapter is ContactsAdapter) { val items = adapter.contacts saveCustomOrderToPrefs(items) @@ -131,7 +144,7 @@ class FavoritesFragment(context: Context, attributeSet: AttributeSet) : MyViewPa } if (context.areSystemAnimationsEnabled) { - fragment_list.scheduleLayoutAnimation() + binding.fragmentList.scheduleLayoutAnimation() } } else { currAdapter.viewType = viewType @@ -140,8 +153,8 @@ class FavoritesFragment(context: Context, attributeSet: AttributeSet) : MyViewPa } fun columnCountChanged() { - (fragment_list.layoutManager as MyGridLayoutManager).spanCount = context!!.config.contactsGridColumnCount - fragment_list?.adapter?.apply { + (binding.fragmentList.layoutManager as MyGridLayoutManager).spanCount = context!!.config.contactsGridColumnCount + binding.fragmentList.adapter?.apply { notifyItemRangeChanged(0, allContacts.size) } } @@ -169,7 +182,7 @@ class FavoritesFragment(context: Context, attributeSet: AttributeSet) : MyViewPa } private fun setupLetterFastScroller(contacts: List) { - letter_fastscroller.setupWithRecyclerView(fragment_list, { position -> + binding.letterFastscroller.setupWithRecyclerView(binding.fragmentList, { position -> try { val name = contacts[position].getNameToDisplay() val character = if (name.isNotEmpty()) name.substring(0, 1) else "" @@ -181,8 +194,8 @@ class FavoritesFragment(context: Context, attributeSet: AttributeSet) : MyViewPa } override fun onSearchClosed() { - fragment_placeholder.beVisibleIf(allContacts.isEmpty()) - (fragment_list.adapter as? ContactsAdapter)?.updateItems(allContacts) + binding.fragmentPlaceholder.beVisibleIf(allContacts.isEmpty()) + (binding.fragmentList.adapter as? ContactsAdapter)?.updateItems(allContacts) setupLetterFastScroller(allContacts) } @@ -193,8 +206,8 @@ class FavoritesFragment(context: Context, attributeSet: AttributeSet) : MyViewPa it.name.startsWith(text, true) }.toMutableList() as ArrayList - fragment_placeholder.beVisibleIf(contacts.isEmpty()) - (fragment_list.adapter as? ContactsAdapter)?.updateItems(contacts, text) + binding.fragmentPlaceholder.beVisibleIf(contacts.isEmpty()) + (binding.fragmentList.adapter as? ContactsAdapter)?.updateItems(contacts, text) setupLetterFastScroller(contacts) } @@ -202,12 +215,12 @@ class FavoritesFragment(context: Context, attributeSet: AttributeSet) : MyViewPa val spanCount = context.config.contactsGridColumnCount val layoutManager = if (viewType == VIEW_TYPE_GRID) { - letter_fastscroller.beGone() + binding.letterFastscroller.beGone() MyGridLayoutManager(context, spanCount) } else { - letter_fastscroller.beVisible() + binding.letterFastscroller.beVisible() MyLinearLayoutManager(context) } - fragment_list.layoutManager = layoutManager + binding.fragmentList.layoutManager = layoutManager } } diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/fragments/MyViewPagerFragment.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/fragments/MyViewPagerFragment.kt index faff87ae..e9df7c73 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/fragments/MyViewPagerFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/fragments/MyViewPagerFragment.kt @@ -9,18 +9,20 @@ import com.simplemobiletools.commons.extensions.getProperTextColor import com.simplemobiletools.commons.extensions.getTextSize import com.simplemobiletools.commons.helpers.SORT_BY_FIRST_NAME import com.simplemobiletools.commons.helpers.SORT_BY_SURNAME +import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.dialer.activities.MainActivity import com.simplemobiletools.dialer.activities.SimpleActivity import com.simplemobiletools.dialer.adapters.ContactsAdapter import com.simplemobiletools.dialer.adapters.RecentCallsAdapter +import com.simplemobiletools.dialer.databinding.FragmentLettersLayoutBinding +import com.simplemobiletools.dialer.databinding.FragmentRecentsBinding import com.simplemobiletools.dialer.extensions.config import com.simplemobiletools.dialer.helpers.Config -import kotlinx.android.synthetic.main.fragment_letters_layout.view.fragment_list -import kotlinx.android.synthetic.main.fragment_recents.view.recents_list -abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) : RelativeLayout(context, attributeSet) { +abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) : + RelativeLayout(context, attributeSet) { protected var activity: SimpleActivity? = null - + protected lateinit var innerBinding: BINDING private lateinit var config: Config fun setupFragment(activity: SimpleActivity) { @@ -35,7 +37,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) fun startNameWithSurnameChanged(startNameWithSurname: Boolean) { if (this !is RecentsFragment) { - (fragment_list.adapter as? ContactsAdapter)?.apply { + (innerBinding.fragmentList?.adapter as? ContactsAdapter)?.apply { config.sorting = if (startNameWithSurname) SORT_BY_SURNAME else SORT_BY_FIRST_NAME (this@MyViewPagerFragment.activity!! as MainActivity).refreshFragments() } @@ -43,18 +45,18 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) } fun finishActMode() { - (fragment_list?.adapter as? MyRecyclerViewAdapter)?.finishActMode() - (recents_list?.adapter as? MyRecyclerViewAdapter)?.finishActMode() + (innerBinding.fragmentList?.adapter as? MyRecyclerViewAdapter)?.finishActMode() + (innerBinding.recentsList?.adapter as? MyRecyclerViewAdapter)?.finishActMode() } fun fontSizeChanged() { if (this is RecentsFragment) { - (recents_list?.adapter as? RecentCallsAdapter)?.apply { + (innerBinding.recentsList?.adapter as? RecentCallsAdapter)?.apply { fontSize = activity.getTextSize() notifyDataSetChanged() } } else { - (fragment_list?.adapter as? ContactsAdapter)?.apply { + (innerBinding.fragmentList?.adapter as? ContactsAdapter)?.apply { fontSize = activity.getTextSize() notifyDataSetChanged() } @@ -68,4 +70,19 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) abstract fun onSearchClosed() abstract fun onSearchQueryChanged(text: String) + + interface InnerBinding { + val fragmentList: MyRecyclerView? + val recentsList: MyRecyclerView? + } + + class LettersInnerBinding(val binding: FragmentLettersLayoutBinding) : InnerBinding { + override val fragmentList: MyRecyclerView = binding.fragmentList + override val recentsList = null + } + + class RecentsInnerBinding(val binding: FragmentRecentsBinding) : InnerBinding { + override val fragmentList = null + override val recentsList = binding.recentsList + } } diff --git a/app/src/main/kotlin/com/simplemobiletools/dialer/fragments/RecentsFragment.kt b/app/src/main/kotlin/com/simplemobiletools/dialer/fragments/RecentsFragment.kt index 2ef37e88..d3e9ebc3 100644 --- a/app/src/main/kotlin/com/simplemobiletools/dialer/fragments/RecentsFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/dialer/fragments/RecentsFragment.kt @@ -13,19 +13,25 @@ import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.dialer.R import com.simplemobiletools.dialer.activities.SimpleActivity import com.simplemobiletools.dialer.adapters.RecentCallsAdapter +import com.simplemobiletools.dialer.databinding.FragmentRecentsBinding import com.simplemobiletools.dialer.extensions.config import com.simplemobiletools.dialer.helpers.MIN_RECENTS_THRESHOLD import com.simplemobiletools.dialer.helpers.RecentsHelper import com.simplemobiletools.dialer.interfaces.RefreshItemsListener import com.simplemobiletools.dialer.models.RecentCall -import kotlinx.android.synthetic.main.fragment_recents.view.recents_list -import kotlinx.android.synthetic.main.fragment_recents.view.recents_placeholder -import kotlinx.android.synthetic.main.fragment_recents.view.recents_placeholder_2 -class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet), RefreshItemsListener { +class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet), + RefreshItemsListener { + private lateinit var binding: FragmentRecentsBinding private var allRecentCalls = listOf() private var recentsAdapter: RecentCallsAdapter? = null + override fun onFinishInflate() { + super.onFinishInflate() + binding = FragmentRecentsBinding.bind(this) + innerBinding = RecentsInnerBinding(binding) + } + override fun setupFragment() { val placeholderResId = if (context.hasPermission(PERMISSION_READ_CALL_LOG)) { R.string.no_previous_calls @@ -33,8 +39,8 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage R.string.could_not_access_the_call_history } - recents_placeholder.text = context.getString(placeholderResId) - recents_placeholder_2.apply { + binding.recentsPlaceholder.text = context.getString(placeholderResId) + binding.recentsPlaceholder2.apply { underlineText() setOnClickListener { requestCallLogPermission() @@ -43,8 +49,8 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage } override fun setupColors(textColor: Int, primaryColor: Int, properPrimaryColor: Int) { - recents_placeholder.setTextColor(textColor) - recents_placeholder_2.setTextColor(properPrimaryColor) + binding.recentsPlaceholder.setTextColor(textColor) + binding.recentsPlaceholder2.setTextColor(properPrimaryColor) recentsAdapter?.apply { initDrawables() @@ -73,17 +79,20 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage private fun gotRecents(recents: List) { if (recents.isEmpty()) { - recents_placeholder.beVisible() - recents_placeholder_2.beGoneIf(context.hasPermission(PERMISSION_READ_CALL_LOG)) - recents_list.beGone() + binding.apply { + recentsPlaceholder.beVisible() + recentsPlaceholder2.beGoneIf(context.hasPermission(PERMISSION_READ_CALL_LOG)) + recentsList.beGone() + } } else { - recents_placeholder.beGone() - recents_placeholder_2.beGone() - recents_list.beVisible() + binding.apply { + recentsPlaceholder.beGone() + recentsPlaceholder2.beGone() + recentsList.beVisible() + } - val currAdapter = recents_list.adapter - if (currAdapter == null) { - recentsAdapter = RecentCallsAdapter(activity as SimpleActivity, recents.toMutableList(), recents_list, this, true) { + if (binding.recentsList.adapter == null) { + recentsAdapter = RecentCallsAdapter(activity as SimpleActivity, recents.toMutableList(), binding.recentsList, this, true) { val recentCall = it as RecentCall if (context.config.showCallConfirmation) { CallConfirmationDialog(activity as SimpleActivity, recentCall.name) { @@ -94,13 +103,13 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage } } - recents_list.adapter = recentsAdapter + binding.recentsList.adapter = recentsAdapter if (context.areSystemAnimationsEnabled) { - recents_list.scheduleLayoutAnimation() + binding.recentsList.scheduleLayoutAnimation() } - recents_list.endlessScrollListener = object : MyRecyclerView.EndlessScrollListener { + binding.recentsList.endlessScrollListener = object : MyRecyclerView.EndlessScrollListener { override fun updateTop() {} override fun updateBottom() { @@ -136,8 +145,8 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage private fun requestCallLogPermission() { activity?.handlePermission(PERMISSION_READ_CALL_LOG) { if (it) { - recents_placeholder.text = context.getString(R.string.no_previous_calls) - recents_placeholder_2.beGone() + binding.recentsPlaceholder.text = context.getString(R.string.no_previous_calls) + binding.recentsPlaceholder2.beGone() val groupSubsequentCalls = context?.config?.groupSubsequentCalls ?: false RecentsHelper(context).getRecentCalls(groupSubsequentCalls) { recents -> @@ -150,7 +159,7 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage } override fun onSearchClosed() { - recents_placeholder.beVisibleIf(allRecentCalls.isEmpty()) + binding.recentsPlaceholder.beVisibleIf(allRecentCalls.isEmpty()) recentsAdapter?.updateItems(allRecentCalls) } @@ -161,7 +170,7 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage it.name.startsWith(text, true) }.toMutableList() as ArrayList - recents_placeholder.beVisibleIf(recentCalls.isEmpty()) + binding.recentsPlaceholder.beVisibleIf(recentCalls.isEmpty()) recentsAdapter?.updateItems(recentCalls, text) } } diff --git a/app/src/main/res/drawable/ic_call_decline.xml b/app/src/main/res/drawable/ic_call_end.xml similarity index 100% rename from app/src/main/res/drawable/ic_call_decline.xml rename to app/src/main/res/drawable/ic_call_end.xml diff --git a/app/src/main/res/layout/activity_call.xml b/app/src/main/res/layout/activity_call.xml index 5e2dd1d7..acd59875 100644 --- a/app/src/main/res/layout/activity_call.xml +++ b/app/src/main/res/layout/activity_call.xml @@ -282,7 +282,7 @@ android:layout_width="@dimen/dialpad_button_size" android:layout_height="@dimen/dialpad_button_size" android:contentDescription="@string/end_call" - android:src="@drawable/ic_call_decline" + android:src="@drawable/ic_call_end" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -318,7 +318,7 @@ android:clickable="false" android:contentDescription="@string/decline_call" android:padding="@dimen/medium_margin" - android:src="@drawable/ic_call_decline" + android:src="@drawable/ic_call_end" app:layout_constraintBottom_toBottomOf="@+id/call_draggable" app:layout_constraintEnd_toStartOf="@+id/call_draggable" app:layout_constraintHorizontal_bias="0.5" diff --git a/build.gradle b/build.gradle index b678690d..a2032dff 100644 --- a/build.gradle +++ b/build.gradle @@ -1,13 +1,13 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.7.10' + ext.kotlin_version = '1.9.0' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.3.1' + classpath 'com.android.tools.build:gradle:8.1.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong diff --git a/gradle.properties b/gradle.properties index 23339e0d..0dd29572 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx1536m +org.gradle.jvmargs=-Xmx4g # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects @@ -17,5 +17,6 @@ org.gradle.jvmargs=-Xmx1536m android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true +android.nonTransitiveRClass=false # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0fde555a..cd00303f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip