简体   繁体   中英

Swipe to reply in chat message like whats app programmatically in android

I am currently working on chat application. I need swipe to reply a particular message like WhatsApp in android programmatically. kindly help me to achieve this. thanks in advance.

link I am referring https://github.com/shainsingh89/SwipeToReply .

滑动回复

Well, here I will list the main challenges with the proposed solutions, you can find the entire project on the github over here :

Challenge 1: New layouts with the quoted text

  1. Adding two new chat message layouts for the sender & receiver send_message_quoted_row & received_message_quoted_row ->> The layout can just be better than that but it's not a big deal for now.

  2. Modifying MessageAdapter to accept them as a new type, and update the quote text in onBindViewHolder :

    private fun getItemViewType(message: Message): Int {
        return if (message.type == MessageType.SEND)
            if (message.quotePos == -1) R.layout.send_message_row
            else R.layout.send_message_quoted_row
        else
            if (message.quotePos == -1) R.layout.received_message_row
            else R.layout.received_message_quoted_row
    }

    override fun onBindViewHolder(holder: MessageViewHolder, position: Int) {
        val message = messageList[position]
        holder.txtSendMsg.text = message.body
        holder.txtQuotedMsg?.text = message.quote
    }

    class MessageViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        var txtSendMsg = view.txtBody!!
        var txtQuotedMsg: TextView? = view.textQuote
    }
  1. Adding new constructor to the Message data class to accept the quote and the position of the original message (which is quoted in the current message
data class Message(var body: String, var time: Long, var type: Int) {

    var quote: String = ""
    var quotePos: Int = -1

    constructor(
        body: String,
        time: Long,
        type: Int,
        quote: String,
        quotePos: Int
    ) : this(body, time, type) {
        this.quote = quote
        this.quotePos = quotePos
    }

}

object MessageType {
    const val SEND = 1
    const val RECEIVED = 2
}
  1. Adding sample quoted messages for testing in SampleMessages

Challenge 2: Embed the quote layout into the reply layout animated like WhatsApp

In WhatsApp: the quote layout appears as a part of the reply layout, and it gradually comes from bottom to top behind the original layout. Also when the cancel button is pressed, it reverses the animation to the bottom.

  • Solved by using a custom Animation class by changing the height of the quoted TextView , and then using View.Gone/Visible to show the layout.
class ResizeAnim(var view: View, private val startHeight: Int, private val targetHeight: Int) :
    Animation() {

    override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
        if (startHeight == 0 || targetHeight == 0) {
            view.layoutParams.height =
                (startHeight + (targetHeight - startHeight) * interpolatedTime).toInt()
        } else {
            view.layoutParams.height = (startHeight + targetHeight * interpolatedTime).toInt()
        }
        view.requestLayout()
    }

    override fun willChangeBounds(): Boolean {
        return true
    }
}

And handle this animation within the activity showQuotedMessage() & hideReplyLayout()

private fun hideReplyLayout() {

    val resizeAnim = ResizeAnim(reply_layout, mainActivityViewModel.currentMessageHeight, 0)
    resizeAnim.duration = ANIMATION_DURATION

    Handler().postDelayed({
        reply_layout.layout(0, -reply_layout.height, reply_layout.width, 0)
        reply_layout.requestLayout()
        reply_layout.forceLayout()
        reply_layout.visibility = View.GONE

    }, ANIMATION_DURATION - 50)

    reply_layout.startAnimation(resizeAnim)
    mainActivityViewModel.currentMessageHeight = 0

    resizeAnim.setAnimationListener(object : Animation.AnimationListener {
        override fun onAnimationStart(animation: Animation?) {
        }

        override fun onAnimationEnd(animation: Animation?) {
            val params = reply_layout.layoutParams
            params.height = 0
            reply_layout.layoutParams = params
        }

        override fun onAnimationRepeat(animation: Animation?) {
        }
    })

}

private fun showQuotedMessage(message: Message) {
    edit_message.requestFocus()
    val inputMethodManager =
        getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    inputMethodManager.showSoftInput(edit_message, InputMethodManager.SHOW_IMPLICIT)

    textQuotedMessage.text = message.body
    val height = textQuotedMessage.getActualHeight()
    val startHeight = mainActivityViewModel.currentMessageHeight

    if (height != startHeight) {

        if (reply_layout.visibility == View.GONE)
            Handler().postDelayed({
                reply_layout.visibility = View.VISIBLE
            }, 50)

        val targetHeight = height - startHeight

        val resizeAnim =
            ResizeAnim(
                reply_layout,
                startHeight,
                targetHeight
            )

        resizeAnim.duration = ANIMATION_DURATION
        reply_layout.startAnimation(resizeAnim)

        mainActivityViewModel.currentMessageHeight = height

    }

}

private fun TextView.getActualHeight(): Int {
    textQuotedMessage.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
    return this.measuredHeight
}

Challenge 3: Calculating the real value of the new quoted text height

Especially when the quoted text height need to be expanded/shrink when the user swipes another message of a different height while there is currently a quoted message.

  • Handled by using getHeight() function to programmatically inflate the quoted TextView and set its text to the new text, compare its height to the height of the old text, and manipulate the animation accordingly.

  • This already covered in the top methods, and I tracked the old height in the ViewModel using currentMessageHeight integer.

Challenge 4: Adding OnClickListener to the quoted message

  • So to go to the original position of the quoted message, we registered this in the Message class as a field, when it's -1, then it's not a quoted message; otherwise it is a quoted message.
  • The click listener is handled with a custom QuoteClickListener interface in the MessageAdapter

Preview:

Adding a new Message:

You should read this for swipe to reply to chat messages hope it'll help you https://medium.com/mindorks/swipe-to-reply-android-recycler-view-ui-c11365f8999f

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM