mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-14 06:52:19 +00:00
Implement InputBarButton
This commit is contained in:
@@ -4,11 +4,15 @@ import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.RelativeLayout
|
||||
import kotlinx.android.synthetic.main.view_input_bar.view.*
|
||||
import network.loki.messenger.R
|
||||
|
||||
class InputBar : LinearLayout {
|
||||
|
||||
private val attachmentsButton by lazy { InputBarButton(context, R.drawable.ic_plus_24) }
|
||||
private val microphoneButton by lazy { InputBarButton(context, R.drawable.ic_microphone) }
|
||||
|
||||
// region Lifecycle
|
||||
constructor(context: Context) : super(context) {
|
||||
setUpViewHierarchy()
|
||||
@@ -24,7 +28,11 @@ class InputBar : LinearLayout {
|
||||
|
||||
private fun setUpViewHierarchy() {
|
||||
LayoutInflater.from(context).inflate(R.layout.view_input_bar, this)
|
||||
attachmentsButtonContainer.addView(attachmentsButton)
|
||||
attachmentsButton.layoutParams = RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT)
|
||||
attachmentsButton.setOnClickListener { }
|
||||
microphoneButtonContainer.addView(microphoneButton)
|
||||
microphoneButton.layoutParams = RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT)
|
||||
microphoneButton.setOnClickListener { }
|
||||
}
|
||||
// endregion
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
package org.thoughtcrime.securesms.conversation.v2.input_bar
|
||||
|
||||
import android.animation.PointFEvaluator
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.PointF
|
||||
import android.util.AttributeSet
|
||||
import android.view.Gravity
|
||||
import android.view.MotionEvent
|
||||
import android.widget.ImageView
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.annotation.DrawableRes
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.loki.utilities.*
|
||||
import org.thoughtcrime.securesms.loki.views.GlowViewUtilities
|
||||
import org.thoughtcrime.securesms.loki.views.InputBarButtonImageViewContainer
|
||||
|
||||
class InputBarButton : RelativeLayout {
|
||||
@DrawableRes private var iconID = 0
|
||||
|
||||
companion object {
|
||||
val animationDuration = 250.toLong()
|
||||
}
|
||||
|
||||
private val expandedImageViewPosition by lazy { PointF(0.0f, 0.0f) }
|
||||
private val collapsedImageViewPosition by lazy { PointF((expandedSize - collapsedSize) / 2, (expandedSize - collapsedSize) / 2) }
|
||||
|
||||
val expandedSize by lazy { resources.getDimension(R.dimen.input_bar_button_expanded_size) }
|
||||
val collapsedSize by lazy { resources.getDimension(R.dimen.input_bar_button_collapsed_size) }
|
||||
|
||||
private val imageViewContainer by lazy {
|
||||
val result = InputBarButtonImageViewContainer(context)
|
||||
val size = collapsedSize.toInt()
|
||||
result.layoutParams = LayoutParams(size, size)
|
||||
result.setBackgroundResource(R.drawable.input_bar_button_background)
|
||||
result.mainColor = resources.getColorWithID(R.color.input_bar_button_background, context.theme)
|
||||
result
|
||||
}
|
||||
|
||||
private val imageView by lazy {
|
||||
val result = ImageView(context)
|
||||
val size = toPx(16, resources)
|
||||
result.layoutParams = LayoutParams(size, size)
|
||||
result.scaleType = ImageView.ScaleType.CENTER_INSIDE
|
||||
result.setImageResource(iconID)
|
||||
result.imageTintList = ColorStateList.valueOf(resources.getColorWithID(R.color.text, context.theme))
|
||||
result
|
||||
}
|
||||
|
||||
constructor(context: Context) : super(context) { throw IllegalAccessException("Use InputBarButton(context:iconID:) instead.") }
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { throw IllegalAccessException("Use InputBarButton(context:iconID:) instead.") }
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { throw IllegalAccessException("Use InputBarButton(context:iconID:) instead.") }
|
||||
|
||||
constructor(context: Context, @DrawableRes iconID: Int) : super(context) {
|
||||
this.iconID = iconID
|
||||
val size = resources.getDimension(R.dimen.input_bar_button_expanded_size).toInt()
|
||||
val layoutParams = LayoutParams(size, size)
|
||||
this.layoutParams = layoutParams
|
||||
addView(imageViewContainer)
|
||||
imageViewContainer.x = collapsedImageViewPosition.x
|
||||
imageViewContainer.y = collapsedImageViewPosition.y
|
||||
imageViewContainer.addView(imageView)
|
||||
val imageViewLayoutParams = imageView.layoutParams as LayoutParams
|
||||
imageViewLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT)
|
||||
imageView.layoutParams = imageViewLayoutParams
|
||||
gravity = Gravity.TOP or Gravity.LEFT // Intentionally not Gravity.START
|
||||
}
|
||||
|
||||
fun expand() {
|
||||
GlowViewUtilities.animateColorChange(context, imageViewContainer, R.color.input_bar_button_background, R.color.accent)
|
||||
imageViewContainer.animateSizeChange(R.dimen.input_bar_button_collapsed_size, R.dimen.input_bar_button_expanded_size, animationDuration)
|
||||
animateImageViewContainerPositionChange(collapsedImageViewPosition, expandedImageViewPosition)
|
||||
}
|
||||
|
||||
fun collapse() {
|
||||
GlowViewUtilities.animateColorChange(context, imageViewContainer, R.color.accent, R.color.input_bar_button_background)
|
||||
imageViewContainer.animateSizeChange(R.dimen.input_bar_button_expanded_size, R.dimen.input_bar_button_collapsed_size, animationDuration)
|
||||
animateImageViewContainerPositionChange(expandedImageViewPosition, collapsedImageViewPosition)
|
||||
}
|
||||
|
||||
private fun animateImageViewContainerPositionChange(startPosition: PointF, endPosition: PointF) {
|
||||
val animation = ValueAnimator.ofObject(PointFEvaluator(), startPosition, endPosition)
|
||||
animation.duration = animationDuration
|
||||
animation.addUpdateListener { animator ->
|
||||
val point = animator.animatedValue as PointF
|
||||
imageViewContainer.x = point.x
|
||||
imageViewContainer.y = point.y
|
||||
}
|
||||
animation.start()
|
||||
}
|
||||
|
||||
override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN -> { expand() }
|
||||
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { collapse() }
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -7,9 +7,12 @@ import android.graphics.*
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.view.ViewOutlineProvider
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.ColorRes
|
||||
import androidx.appcompat.widget.AppCompatImageView
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.loki.utilities.getColorWithID
|
||||
import org.thoughtcrime.securesms.loki.utilities.toPx
|
||||
@@ -155,4 +158,36 @@ class PathDotView : View, GlowView {
|
||||
super.onDraw(c)
|
||||
}
|
||||
// endregion
|
||||
}
|
||||
}
|
||||
|
||||
class InputBarButtonImageViewContainer : RelativeLayout, GlowView {
|
||||
@ColorInt override var mainColor: Int = 0
|
||||
set(newValue) { field = newValue; paint.color = newValue }
|
||||
@ColorInt override var sessionShadowColor: Int = 0 // Unused
|
||||
|
||||
private val paint: Paint by lazy {
|
||||
val result = Paint()
|
||||
result.style = Paint.Style.FILL
|
||||
result.isAntiAlias = true
|
||||
result
|
||||
}
|
||||
|
||||
// region Lifecycle
|
||||
constructor(context: Context) : super(context) { }
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { }
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { }
|
||||
|
||||
init {
|
||||
setWillNotDraw(false)
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region Updating
|
||||
override fun onDraw(c: Canvas) {
|
||||
val w = width.toFloat()
|
||||
val h = height.toFloat()
|
||||
c.drawCircle(w / 2, h / 2, w / 2, paint)
|
||||
super.onDraw(c)
|
||||
}
|
||||
// endregion
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user