国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android仿微信朋友圈點(diǎn)擊評(píng)論自動(dòng)定位到相關(guān)行功能

2019-12-12 00:51:35
字體:
供稿:網(wǎng)友

最近閑來無事,隨便看看各種UI實(shí)現(xiàn)的代碼

本文涉及到的相關(guān)代碼已經(jīng)上傳到 https://github.com/r17171709/android_demo/tree/master/WeixinEditText

打開你的微信朋友圈,點(diǎn)擊評(píng)論,你就會(huì)發(fā)現(xiàn)有一個(gè)小細(xì)節(jié):文本輸入框的高度恰好定位到這條信息的底部位置

這個(gè)實(shí)現(xiàn)起來其實(shí)很簡(jiǎn)單,咱們就來看看吧

最簡(jiǎn)單的RecyclerView

依然是先實(shí)現(xiàn)RecyclerView。跟朋友圈一樣,我們也把頭給加上去,這樣我們?cè)邳c(diǎn)第一條信息的時(shí)候,效果會(huì)更好一些

信息內(nèi)容簡(jiǎn)單些,反正我們就看看效果

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:orientation="vertical" android:layout_width="match_parent"  android:layout_height="wrap_content">  <TextView    android:id="@+id/tv_title"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:textSize="12sp" />  <TextView    android:id="@+id/tv_comment"    android:text="評(píng)論"    android:textSize="14sp"    android:layout_margin="5dip"    android:textColor="@color/colorAccent"    android:layout_width="wrap_content"    android:layout_height="wrap_content" /></LinearLayout>

頭部也很簡(jiǎn)單,就一張圖片作為區(qū)分

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="match_parent" android:layout_height="300dip">  <ImageView    android:layout_centerInParent="true"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:src="@mipmap/ic_launcher"/></RelativeLayout>

消息內(nèi)容就以string作為信息數(shù)據(jù)類型,頭的數(shù)據(jù)類型為TopClass

data class TopClass(val value: String)

實(shí)現(xiàn)一個(gè)adapter

class MainAdapter(private val beans: ArrayList<Any>, val context: Context) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {  var height = 0  enum class TYPE(val value: Int) {    TOP(0), NORMAL(1)  }  override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder {    when(viewType) {      TYPE.NORMAL.value -> {        val view = LayoutInflater.from(context).inflate(R.layout.adapter_main, parent, false)        return MainNormalViewHolder(view)      }      TYPE.TOP.value -> {        val view = LayoutInflater.from(context).inflate(R.layout.adapter_top, parent, false)        return MainTopViewHolder(view)      }    }    throw Exception()  }  override fun getItemCount() = beans.size  override fun onBindViewHolder(holder: RecyclerView.ViewHolder?, position: Int) {    if (holder != null) {      when(getItemViewType(position)) {        TYPE.NORMAL.value -> {          (holder as MainNormalViewHolder).setText(beans[position] as String)          holder.clickComment(holder.layoutPosition)        }        TYPE.TOP.value -> {}      }    }  }  override fun getItemViewType(position: Int): Int {    when(beans[position]) {      is String -> return TYPE.NORMAL.value      is TopClass -> return TYPE.TOP.value    }    return super.getItemViewType(position)  }  inner class MainNormalViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {    fun setText(text: String) {      itemView.tv_title.text = text    }    fun clickComment(position: Int) {      itemView.tv_comment.setOnClickListener {        (context as MainActivity).showInputComment(itemView.tv_comment, position)      }    }  }  inner class MainTopViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)}

這樣一個(gè)列表就完成了

輸入框的產(chǎn)生

這里有一個(gè)關(guān)鍵的地方,如何將EditText懸浮在鍵盤上,并且RecyclerView不會(huì)被擠上去。這里我們可以使用Dialog,同時(shí)在布局中要使用ScrollView來進(jìn)行占位

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:orientation="vertical"  android:layout_width="match_parent"  android:layout_height="match_parent">  <ScrollView    android:layout_width="match_parent"    android:layout_height="match_parent"    android:layout_weight="1">  </ScrollView>  <View    android:layout_width="match_parent"    android:layout_height="0.5dip"    android:background="#666666"></View>  <LinearLayout    android:id="@+id/dialog_layout_comment"    android:layout_width="match_parent"    android:layout_height="wrap_content">    <EditText      android:layout_width="match_parent"      android:layout_height="wrap_content"      android:layout_weight="1"/>    <Button      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:text="確認(rèn)"/>  </LinearLayout></LinearLayout>

只有ScrollView進(jìn)行配合,才能實(shí)現(xiàn)我們的效果。

來看看效果

列表的滾動(dòng)

輸入框也有了,這時(shí)候就差滾動(dòng)了。我們可以通過smoothScrollBy來讓RecyclerView按X或者Y軸進(jìn)行滾動(dòng)。那我們這里到底應(yīng)該滾動(dòng)多少距離才對(duì)呢?,咱們來計(jì)算一下吧

圖中紅色部分為鍵盤展現(xiàn)之前某條信息評(píng)論區(qū)所在位置;藍(lán)色部分為鍵盤,當(dāng)鍵盤打開的時(shí)候,我們需要將紅色的部分移動(dòng)到黃色的位置。這樣黃色頂部與紅色頂部中間的區(qū)域高度,就是RecyclerView需要滾動(dòng)的數(shù)值這樣就好辦了,我們使用getLocationOnScreen去獲取差值,再加上評(píng)論區(qū)域高度就行了

fun showInputComment(commentView: View, position: Int) {  // RV中評(píng)論區(qū)起始Y的位置  val rvInputY = getY(commentView)  val rvInputHeight = commentView.height  dialog = Dialog(this, android.R.style.Theme_Translucent_NoTitleBar)  dialog!!.setContentView(R.layout.dialog_comment)  dialog!!.show()  val handler = object : Handler() {}  handler.postDelayed({    // 對(duì)話框中的輸入框Y的位置    val dialogY = getY(dialog!!.findViewById<LinearLayout>(R.id.dialog_layout_comment))    rv_main.smoothScrollBy(0, rvInputY - (dialogY - rvInputHeight))  }, 300)}private fun getY(view: View): Int {  val rect = IntArray(2)  view.getLocationOnScreen(rect)  return rect[1]}

來看看效果

但是還有幾個(gè)小問題,如果是點(diǎn)擊最后一行的話,會(huì)因?yàn)闈L動(dòng)空間不足而不能實(shí)現(xiàn)相同的效果,并且按返回鍵的時(shí)候,鍵盤先消失,然后再按一次之后Dialog才消失。

針對(duì)第一個(gè)問題,我們直接添加一個(gè)空View作為列表最后一項(xiàng)即可,并且高度要等于輸入框的高度;第二個(gè)問題也很簡(jiǎn)單,就是監(jiān)聽鍵盤彈出與隱藏時(shí)View高度發(fā)生的變化

data class BottomClass(val value: String)

點(diǎn)擊的時(shí)候再添加

handler.postDelayed({  // 對(duì)話框中的輸入框Y的位置  val dialogY = getY(dialog!!.findViewById<LinearLayout>(R.id.dialog_layout_comment))  if (position == arrays.size - 1) {    arrays.add(BottomClass(""))    adapter?.height = dialog!!.findViewById<LinearLayout>(R.id.dialog_layout_comment).height    adapter?.notifyDataSetChanged()  }  rv_main.smoothScrollBy(0, rvInputY - (dialogY - rvInputHeight))}, 300)

關(guān)閉Dialog的時(shí)候刪除這個(gè)對(duì)象

window.decorView.viewTreeObserver.addOnGlobalLayoutListener {  val rect = Rect()  window.decorView.getWindowVisibleDisplayFrame(rect)  val displayHeight = rect.bottom - rect.top  val height = window.decorView.height  val keyboardHeight = height - displayHeight  if (previousKeyboardHeight != keyboardHeight) {    val hide = displayHeight.toDouble() / height > 0.8    if (hide) {      if (arrays[arrays.size - 1] is BottomClass) {        arrays.removeAt(arrays.size - 1)        adapter?.notifyDataSetChanged()      }      dialog?.dismiss()    }  }}

來看看最終效果

總結(jié)

以上所述是小編給大家介紹的Android仿微信朋友圈點(diǎn)擊評(píng)論自動(dòng)定位到相關(guān)行功能,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)武林網(wǎng)網(wǎng)站的支持!

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 桑日县| 阿鲁科尔沁旗| 江口县| 龙州县| 宁武县| 边坝县| 芒康县| 通江县| 克什克腾旗| 庆城县| 云梦县| 巨野县| 钦州市| 钟祥市| 嘉荫县| 贺州市| 北海市| 岳阳市| 威海市| 衢州市| 辽宁省| 乌兰县| 休宁县| 东丽区| 苗栗市| 上思县| 龙里县| 闽清县| 宁明县| 商河县| 西丰县| 江川县| 龙川县| 喀什市| 绥滨县| 沂南县| 铜川市| 潢川县| 洪雅县| 玛纳斯县| 黄石市|