recyclerview有了item的資料列表以後,想要進一步操作,例如點擊
可以如下進行
在item.xml的屬性加上android:background="?android:attr/selectableItemBackground"
在Adapter中建立控制點擊的interface,於MainActivity實作後
在ViewHolder實作的OnClick取得欲對其操作的item位置與內容
class RvAdapter(private val listener: OnItemClickListener) :
RecyclerView.Adapter<RvAdapter.myHolder>() {
private val list = mutableListOf<Person>()
inner class myHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
val rvName: TextView = itemView.tv_name
val rvAddress: TextView = itemView.tv_address
val rvPhone: TextView = itemView.tv_phone
// 偵測點擊的item,要先放在viewholder class初始化
init {
itemView.setOnClickListener(this)
}
override fun onClick(v: View?) {
val position = adapterPosition
if (position != RecyclerView.NO_POSITION) {
listener.onItemClick(list[position])
}
}
}
interface OnItemClickListener {
fun onItemClick(person: Person)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): myHolder {
val createView = LayoutInflater.from(parent.context).inflate(
R.layout.person_item, parent, false
)
return myHolder(createView)
}
override fun getItemCount(): Int {
return list.size
}
override fun onBindViewHolder(holder: myHolder, position: Int) {
val currentItem = list[position]
holder.rvName.text = currentItem.name
holder.rvAddress.text = currentItem.address
holder.rvPhone.text = currentItem.phone
}
fun update(updateList: List<Person>) {
list.clear()
list.addAll(updateList)
notifyDataSetChanged()
}
}
在MainActivity覆寫interface中的onItemClick方法
例如我們想要點擊item時,把資料帶到dialog做修改動作
class MainActivity : AppCompatActivity(), RvAdapter.OnItemClickListener {
private val myAdapter = RvAdapter(this)
private lateinit var db: PersonDatabase
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
db = PersonDatabase.getInstance(this)
recycler_view.adapter = myAdapter
recycler_view.layoutManager = LinearLayoutManager(this)
val dialogItem = LayoutInflater.from(this).inflate(R.layout.dialog, null)
val confirmButton = dialogItem.findViewById<Button>(R.id.btn_confirm) //新增
val deleteButton = dialogItem.findViewById<Button>(R.id.btn_delete) //刪除
val cancelButton = dialogItem.findViewById<Button>(R.id.btn_cancel)
fab.setOnClickListener {
floatingButton(dialogItem, confirmButton, cancelButton, deleteButton)
}
notifyAdapter()
}
private fun floatingButton(
dialogItem: View,
confirmButton: Button,
cancelButton: Button,
deleteButton: Button
) {
val dialogBuilder = AlertDialog.Builder(this@MainActivity)
val dialog = dialogBuilder
.setTitle("新增/查詢")
.setView(dialogItem)
.setOnDismissListener {
(dialogItem.parent as ViewGroup).removeView(dialogItem)
}
.show()
confirmButton.setOnClickListener {
val item = Person(
dialogItem.ed_name.text.toString(),
dialogItem.ed_phone.text.toString(),
dialogItem.ed_address.text.toString()
)
if (dialogItem.ed_name.text.isNotEmpty() && dialogItem.ed_phone.text.isNotEmpty()) {
db.personDataDao.insert(item)
notifyAdapter()
dialog.dismiss()
} else {
Toast.makeText(this, "請輸入姓名,電話", Toast.LENGTH_SHORT).show()
}
dialogItem.ed_name.text.clear()
dialogItem.ed_phone.text.clear()
dialogItem.ed_address.text.clear()
}
deleteButton.setOnClickListener {
db.personDataDao.clear()
notifyAdapter()
dialog.dismiss()
}
cancelButton.setOnClickListener {
dialogItem.ed_name.text.clear()
dialogItem.ed_phone.text.clear()
dialogItem.ed_address.text.clear()
dialog.dismiss()
}
}
// 點擊修改
override fun onItemClick(person: Person) {
val dialogUpdate = LayoutInflater.from(this).inflate(R.layout.dialog_update, null)
val dialogBuilder = AlertDialog.Builder(this@MainActivity)
val cancelButton = dialogUpdate.findViewById<Button>(R.id.btn_cancel)
val dialog = dialogBuilder
.setTitle("修改項目")
.setView(dialogUpdate)
// 設定當dialog被點掉時,remove原放進來的view(dialogItem),否則再次點fab時會丟exception
.setOnDismissListener {
(dialogUpdate.parent as ViewGroup).removeView(dialogUpdate)
}
.show()
dialogUpdate.ed_name.setText(person.name, TextView.BufferType.EDITABLE)
dialogUpdate.ed_phone.setText(person.phone, TextView.BufferType.EDITABLE)
dialogUpdate.ed_address.setText(person.address, TextView.BufferType.EDITABLE)
dialogUpdate.btn_update.setOnClickListener {
val updateItem = Person(
dialogUpdate.ed_name.text.toString(),
dialogUpdate.ed_phone.text.toString(),
dialogUpdate.ed_address.text.toString(),
person.personId
)
db.personDataDao.update(updateItem)
notifyAdapter()
dialog.dismiss()
}
}
private fun notifyAdapter() {
val itemList = db.personDataDao.getAll()
myAdapter.update(itemList)
}
}
這裡發現到一個問題,點擊時,dialog有時有跳出,有時沒有
以爲是app哪裏卡住
請教導師後發現是點在某些view上面的時候不會跳出,認爲應該是view的問題,可開啓開發人員中的show layout bounds(顯示版面配置界限)確認
再針對view檢查問題
果然發現我的TextView裡面有怪怪的屬性android:inputType
<TextView
...
android:inputType="none|number"
... />
原來因爲我做輸入的dialog跟顯示的item layout長的差不多,我就將xml內容都複製過來
把標籤EditText改成TextView,以及裡面的id屬性改一下而已,沒注意到其它
既然是TextView,只需要顯示,拿掉android:inputType
屬性後
點擊item就都正常了