Android 单击ListAdapter时显示对话框
我有一个包含以下列表适配器的活动,用于显示有关github存储库的一些信息。现在我需要实现,当长按列表项时,显示一个对话框,询问是否应该转到存储库html\u url或所有者html\u url,然后在浏览器中打开 实现这一点的最佳方式是什么?逻辑应该在活动中还是在ListAdapater/ViewHolder中 RepositoryListAdapterAndroid 单击ListAdapter时显示对话框,android,kotlin,android-recyclerview,Android,Kotlin,Android Recyclerview,我有一个包含以下列表适配器的活动,用于显示有关github存储库的一些信息。现在我需要实现,当长按列表项时,显示一个对话框,询问是否应该转到存储库html\u url或所有者html\u url,然后在浏览器中打开 实现这一点的最佳方式是什么?逻辑应该在活动中还是在ListAdapater/ViewHolder中 RepositoryListAdapter 让活动将侦听器传递给适配器以执行此操作 在适配器中,创建侦听器接口: class RepositoryListAdapter(val onI
让活动将侦听器传递给适配器以执行此操作 在适配器中,创建侦听器接口:
class RepositoryListAdapter(val onItemLongClickListener: OnItemLongClickListener) : ListAdapter<Repo, RepositoryListAdapter.RepositoryViewHolder>(
RepositoryDiffCallback()
) {
interface OnItemLongClickListener {
fun onItemLongClick(item: Repo, position: Int)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
RepositoryViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.item_repository,
parent,
false
)
).also { vh ->
vh.itemView.setOnLongClickListener {
val position = vh.adapterPosition
if (position != RecyclerView.NO_POSITION) {
onItemLongClickListener.onItemLongClick(getItem(position), position)
}
true
}
}
}
让活动将侦听器传递给适配器以执行此操作 在适配器中,创建侦听器接口:
class RepositoryListAdapter(val onItemLongClickListener: OnItemLongClickListener) : ListAdapter<Repo, RepositoryListAdapter.RepositoryViewHolder>(
RepositoryDiffCallback()
) {
interface OnItemLongClickListener {
fun onItemLongClick(item: Repo, position: Int)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
RepositoryViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.item_repository,
parent,
false
)
).also { vh ->
vh.itemView.setOnLongClickListener {
val position = vh.adapterPosition
if (position != RecyclerView.NO_POSITION) {
onItemLongClickListener.onItemLongClick(getItem(position), position)
}
true
}
}
}
最好的方法是在适配器中处理长时间单击弹出窗口,并在用户单击以分割/活动之后使用操作
class RepositoryListAdapter : ListAdapter<Repo, RepositoryListAdapter.RepositoryViewHolder>(
RepositoryDiffCallback()
) {
adapter.setPopupListener(object : OnPopupClick {
override fun goToRepository() {
//Consume action
}
override fun goToOwner(){
//Consume action
}
})
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
RepositoryViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.item_repository,
parent,
false
)
)
override fun onBindViewHolder(holder: RepositoryViewHolder, position: Int) {
holder.bind(getItem(position))
}
//WeakReference to prevent un-wanted gc clean of listener
private var popupListener: WeakReference<OnPopupClick>? = null
fun setPopupListener(listener: OnPopupClick) {
popupListener = WeakReference(listener)
}
interface OnPopupClick {
fun goToRepository()
fun goToOwner()
}
class RepositoryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
fun bind(repository: Repo) = with(itemView) {
repositoryName.text = repository.name
repositoryDescription.text = repository.description
ownerLogin.text = repository.owner.login
Glide.with(context)
.load(repository.owner.avatarUrl)
.into(imageView)
itemView.setOnLongClickListener{
onLongClick()
}
if (repository.forksCount > 0) {
itemView.setBackgroundColor(ContextCompat.getColor(context, R.color.light_green))
} else {
itemView.setBackgroundColor(ContextCompat.getColor(context, android.R.color.white))
}
}
fun onLongClick(){
//MenuAnchor must be added to your item view
val popup = PopupMenu(view.context, menuAnchor)
popup.inflate(R.menu.yourMenu) //Customize for user
popup.setOnMenuItemClickListener(object : PopupMenu.OnMenuItemClickListener {
override fun onMenuItemClick(item: MenuItem?): Boolean {
when (item?.itemId) {
R.id.owner -> {
popupListener?.get()?.goToOwner()
return true
}
R.id.repo ->{
popupListener?.get()?.goToRepository()
return true
}
}
return true
}
})
popup.show()
}
}
}
class RepositoryDiffCallback : DiffUtil.ItemCallback<Repo>() {
override fun areItemsTheSame(oldItem: Repo, newItem: Repo): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: Repo, newItem: Repo): Boolean {
return oldItem == newItem
}
}
最好的方法是在适配器中处理长时间单击弹出窗口,并在用户单击以分割/活动之后使用操作
class RepositoryListAdapter : ListAdapter<Repo, RepositoryListAdapter.RepositoryViewHolder>(
RepositoryDiffCallback()
) {
adapter.setPopupListener(object : OnPopupClick {
override fun goToRepository() {
//Consume action
}
override fun goToOwner(){
//Consume action
}
})
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
RepositoryViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.item_repository,
parent,
false
)
)
override fun onBindViewHolder(holder: RepositoryViewHolder, position: Int) {
holder.bind(getItem(position))
}
//WeakReference to prevent un-wanted gc clean of listener
private var popupListener: WeakReference<OnPopupClick>? = null
fun setPopupListener(listener: OnPopupClick) {
popupListener = WeakReference(listener)
}
interface OnPopupClick {
fun goToRepository()
fun goToOwner()
}
class RepositoryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
fun bind(repository: Repo) = with(itemView) {
repositoryName.text = repository.name
repositoryDescription.text = repository.description
ownerLogin.text = repository.owner.login
Glide.with(context)
.load(repository.owner.avatarUrl)
.into(imageView)
itemView.setOnLongClickListener{
onLongClick()
}
if (repository.forksCount > 0) {
itemView.setBackgroundColor(ContextCompat.getColor(context, R.color.light_green))
} else {
itemView.setBackgroundColor(ContextCompat.getColor(context, android.R.color.white))
}
}
fun onLongClick(){
//MenuAnchor must be added to your item view
val popup = PopupMenu(view.context, menuAnchor)
popup.inflate(R.menu.yourMenu) //Customize for user
popup.setOnMenuItemClickListener(object : PopupMenu.OnMenuItemClickListener {
override fun onMenuItemClick(item: MenuItem?): Boolean {
when (item?.itemId) {
R.id.owner -> {
popupListener?.get()?.goToOwner()
return true
}
R.id.repo ->{
popupListener?.get()?.goToRepository()
return true
}
}
return true
}
})
popup.show()
}
}
}
class RepositoryDiffCallback : DiffUtil.ItemCallback<Repo>() {
override fun areItemsTheSame(oldItem: Repo, newItem: Repo): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: Repo, newItem: Repo): Boolean {
return oldItem == newItem
}
}
我最后就是这样做的,以防有人觉得有用 RepositoryListAdapter
我最后就是这样做的,以防有人觉得有用 RepositoryListAdapter
避免在onBindViewHolder中设置任何侦听器,因为此方法将被反复调用。请检查我的答案,以获得更优化的方法。对不起,我忘记了。在适配器位置之前。我编辑了,再次检查。如果您觉得有用,请将其标记为已接受。您能将其更改为以下内容吗?这是第二次,所以它没有得到这个职位。另外{viewHolder->viewHolder.itemView.setOnLongClickListener{val position=viewHolder.adapterPosition if position!=RecyclerView.NO_position{interaction?.onItemLongClickgetItemposition}true}正如我上面所说,onBindViewHolder将被反复调用,因此setOnLongClickListener最终将被不必要地多次调用。避免在onBindViewHolder中设置任何侦听器,因为此方法将被反复调用。请检查我的答案,以获得更优化的方法。对不起,我忘记了。在适配器位置之前。我编辑了,再次检查。如果您觉得有用,请将其标记为已接受。您能将其更改为以下内容吗?这是第二次,所以它没有得到这个职位。另外{viewHolder->viewHolder.itemView.setOnLongClickListener{val position=viewHolder.adapterPosition if position!=RecyclerView.NO_position{interaction?.onItemLongClickgetItemposition}true}看看这个,就像我上面说的,onBindViewHolder会被反复调用,所以setOnLongClickListener最终会被不必要地调用很多次。
adapter.setPopupListener(object : OnPopupClick {
override fun goToRepository() {
//Consume action
}
override fun goToOwner(){
//Consume action
}
})
class RepositoryListAdapter(private val interaction: Interaction? = null) : ListAdapter<Repo, RepositoryListAdapter.RepositoryViewHolder>(
RepositoryDiffCallback()
) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
RepositoryViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.item_repository,
parent,
false
),
interaction
)
override fun onBindViewHolder(holder: RepositoryViewHolder, position: Int) {
holder.bind(getItem(position))
}
class RepositoryViewHolder(itemView: View, private val interaction: Interaction?)
: RecyclerView.ViewHolder(itemView){
fun bind(repository: Repo) = with(itemView) {
repositoryName.text = repository.name
repositoryDescription.text = repository.description
ownerLogin.text = repository.owner.login
Glide.with(context)
.load(repository.owner.avatarUrl)
.into(imageView)
if (repository.forksCount > 0) {
itemView.setBackgroundColor(ContextCompat.getColor(context, R.color.light_green))
} else {
itemView.setBackgroundColor(ContextCompat.getColor(context, android.R.color.white))
}
setOnLongClickListener {
interaction?.onItemLongClick(repository)
true
}
}
}
interface Interaction {
fun onItemLongClick(item: Repo)
}
}
class MainActivity : AppCompatActivity(), RepositoryListAdapter.Interaction {
...
private fun setupListAdapter() {
repositoryListAdapter = RepositoryListAdapter(this)
...
}
private fun showDialog(repo: Repo) {
dialog = AlertDialog.Builder(this)
.setItems(arrayOf("Repository url", "Owner url")) { _, which ->
when (which) {
0 -> openUrl(repo.htmlUrl)
1 -> openUrl(repo.owner.htmlUrl)
}
}.show()
}
private fun openUrl(url: String?) {
url?.let {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
}
}
override fun onItemLongClick(item: Repo) {
showDialog(item)
}
...
}