ප්රතිචක්රීකරණ දර්ශනයට නැත onItemClickListener
මෙම RecyclerView
පැරණි ඊට ප්රතිවිරුද්ධ ලෙස, උපකරණ කට්ටලය වන්නේ ListView
එය ලක්ෂණ අඩු ගොඩනැගීම හා වඩා නම්යශීලී බවක් ඇත. මෙම onItemClickListener
ListView ඉවත් කරමින් සිටින බවත් එකම ලක්ෂණය නොවේ. නමුත් එය ඔබේ අභිමතය පරිදි දිගු කිරීමට සවන්දෙන්නන් හා ක්රමවේදයන් රාශියක් ඇත, එය දකුණු අතේ වඩා බලවත් ය;).
මගේ මතය අනුව ඉවත් කරන ලද වඩාත්ම සංකීර්ණ ලක්ෂණය RecyclerView
වන්නේ වේගවත් අනුචලනයයි . අනෙක් බොහෝ අංග පහසුවෙන් නැවත ක්රියාත්මක කළ හැකිය.
RecyclerView
එකතු කරන ලද වෙනත් සිසිල් අංග මොනවාදැයි දැන ගැනීමට ඔබට අවශ්ය නම් මෙම ප්රශ්නය වෙනත් ප්රශ්නයකට කියවන්න.
මතක කාර්යක්ෂමතාව - onItemClickListener සඳහා අතහැර දැමීමේ විසඳුම
ඇන්ඩ්රොයිඩ් ජීඩීඊ එකක් වන හියුගෝ වීසර් විසින් මෙම විසඳුම යෝජනා කරන ලදී. ඔබේ කේතය අතහැර එය භාවිතා කිරීමට ඔහු ඔබට බලපත්ර රහිත පන්තියක් ලබා දුන්නේය.RecyclerView
එය RecyclerView
භාවිතයෙන් හඳුන්වා දුන් සමහර බහුකාර්යතාවයන් විදහා RecyclerView.OnChildAttachStateChangeListener
දක්වයි.
සංස්කරණය කරන්න 2019 : කොට්ලින් අනුවාදය මා විසින්, ජාවා වන්, හියුගෝ වීසර් වෙතින්, පහතින් තබා ඇත
කොට්ලින් / ජාවා
ගොනුවක් සාදා එය values/ids.xml
තුළට දමන්න:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="item_click_support" type="id" />
</resources>
ඉන්පසු ඔබේ කේතයට පහත කේතය එක් කරන්න
කොට්ලින්
භාවිතය:
recyclerView.onItemClick { recyclerView, position, v ->
// do it
}
(එය දිගු අයිතම ක්ලික් කිරීම සඳහා ද සහාය වන අතර මා එකතු කළ තවත් අංගයක් සඳහා පහත බලන්න).
ක්රියාත්මක කිරීම (හියුගෝ වීසර් ජාවා කේතයට මගේ අනුවර්තනය):
typealias OnRecyclerViewItemClickListener = (recyclerView: RecyclerView, position: Int, v: View) -> Unit
typealias OnRecyclerViewItemLongClickListener = (recyclerView: RecyclerView, position: Int, v: View) -> Boolean
class ItemClickSupport private constructor(private val recyclerView: RecyclerView) {
private var onItemClickListener: OnRecyclerViewItemClickListener? = null
private var onItemLongClickListener: OnRecyclerViewItemLongClickListener? = null
private val attachListener: RecyclerView.OnChildAttachStateChangeListener = object : RecyclerView.OnChildAttachStateChangeListener {
override fun onChildViewAttachedToWindow(view: View) {
// every time a new child view is attached add click listeners to it
val holder = this@ItemClickSupport.recyclerView.getChildViewHolder(view)
.takeIf { it is ItemClickSupportViewHolder } as? ItemClickSupportViewHolder
if (onItemClickListener != null && holder?.isClickable != false) {
view.setOnClickListener(onClickListener)
}
if (onItemLongClickListener != null && holder?.isLongClickable != false) {
view.setOnLongClickListener(onLongClickListener)
}
}
override fun onChildViewDetachedFromWindow(view: View) {
}
}
init {
// the ID must be declared in XML, used to avoid
// replacing the ItemClickSupport without removing
// the old one from the RecyclerView
this.recyclerView.setTag(R.id.item_click_support, this)
this.recyclerView.addOnChildAttachStateChangeListener(attachListener)
}
companion object {
fun addTo(view: RecyclerView): ItemClickSupport {
// if there's already an ItemClickSupport attached
// to this RecyclerView do not replace it, use it
var support: ItemClickSupport? = view.getTag(R.id.item_click_support) as? ItemClickSupport
if (support == null) {
support = ItemClickSupport(view)
}
return support
}
fun removeFrom(view: RecyclerView): ItemClickSupport? {
val support = view.getTag(R.id.item_click_support) as? ItemClickSupport
support?.detach(view)
return support
}
}
private val onClickListener = View.OnClickListener { v ->
val listener = onItemClickListener ?: return@OnClickListener
// ask the RecyclerView for the viewHolder of this view.
// then use it to get the position for the adapter
val holder = this.recyclerView.getChildViewHolder(v)
listener.invoke(this.recyclerView, holder.adapterPosition, v)
}
private val onLongClickListener = View.OnLongClickListener { v ->
val listener = onItemLongClickListener ?: return@OnLongClickListener false
val holder = this.recyclerView.getChildViewHolder(v)
return@OnLongClickListener listener.invoke(this.recyclerView, holder.adapterPosition, v)
}
private fun detach(view: RecyclerView) {
view.removeOnChildAttachStateChangeListener(attachListener)
view.setTag(R.id.item_click_support, null)
}
fun onItemClick(listener: OnRecyclerViewItemClickListener?): ItemClickSupport {
onItemClickListener = listener
return this
}
fun onItemLongClick(listener: OnRecyclerViewItemLongClickListener?): ItemClickSupport {
onItemLongClickListener = listener
return this
}
}
/** Give click-ability and long-click-ability control to the ViewHolder */
interface ItemClickSupportViewHolder {
val isClickable: Boolean get() = true
val isLongClickable: Boolean get() = true
}
// Extension function
fun RecyclerView.addItemClickSupport(configuration: ItemClickSupport.() -> Unit = {}) = ItemClickSupport.addTo(this).apply(configuration)
fun RecyclerView.removeItemClickSupport() = ItemClickSupport.removeFrom(this)
fun RecyclerView.onItemClick(onClick: OnRecyclerViewItemClickListener) {
addItemClickSupport { onItemClick(onClick) }
}
fun RecyclerView.onItemLongClick(onLongClick: OnRecyclerViewItemLongClickListener) {
addItemClickSupport { onItemLongClick(onLongClick) }
}
(ඔබට XML ගොනුවක් එක් කිරීමට අවශ්ය බව මතක තබා ගන්න, මෙම කොටසට ඉහළින් බලන්න)
කෝට්ලින් අනුවාදයේ ප්රසාද ලක්ෂණය
සමහර විට ඔබට ප්රතිචක්රීකරණ දර්ශනයේ සියලුම අයිතම ක්ලික් කළ හැකි නොවේ.
මෙය හැසිරවීමට මම ක්ලික් කළ හැකි අයිතමය පාලනය කිරීමට ItemClickSupportViewHolder
ඔබට භාවිතා කළ හැකි අතුරු මුහුණත හඳුන්වා දී ඇත ViewHolder
.
උදාහරණයක්:
class MyViewHolder(view): RecyclerView.ViewHolder(view), ItemClickSupportViewHolder {
override val isClickable: Boolean get() = false
override val isLongClickable: Boolean get() = false
}
ජාවා
භාවිතය:
ItemClickSupport.addTo(mRecyclerView)
.setOnItemClickListener(new ItemClickSupport.OnItemClickListener() {
@Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
// do it
}
});
(එය දිගු අයිතම ක්ලික් කිරීම සඳහා ද සහාය වේ)
ක්රියාත්මක කිරීම (මා විසින් එකතු කරන ලද අදහස්):
public class ItemClickSupport {
private final RecyclerView mRecyclerView;
private OnItemClickListener mOnItemClickListener;
private OnItemLongClickListener mOnItemLongClickListener;
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mOnItemClickListener != null) {
// ask the RecyclerView for the viewHolder of this view.
// then use it to get the position for the adapter
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
mOnItemClickListener.onItemClicked(mRecyclerView, holder.getAdapterPosition(), v);
}
}
};
private View.OnLongClickListener mOnLongClickListener = new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (mOnItemLongClickListener != null) {
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
return mOnItemLongClickListener.onItemLongClicked(mRecyclerView, holder.getAdapterPosition(), v);
}
return false;
}
};
private RecyclerView.OnChildAttachStateChangeListener mAttachListener
= new RecyclerView.OnChildAttachStateChangeListener() {
@Override
public void onChildViewAttachedToWindow(View view) {
// every time a new child view is attached add click listeners to it
if (mOnItemClickListener != null) {
view.setOnClickListener(mOnClickListener);
}
if (mOnItemLongClickListener != null) {
view.setOnLongClickListener(mOnLongClickListener);
}
}
@Override
public void onChildViewDetachedFromWindow(View view) {
}
};
private ItemClickSupport(RecyclerView recyclerView) {
mRecyclerView = recyclerView;
// the ID must be declared in XML, used to avoid
// replacing the ItemClickSupport without removing
// the old one from the RecyclerView
mRecyclerView.setTag(R.id.item_click_support, this);
mRecyclerView.addOnChildAttachStateChangeListener(mAttachListener);
}
public static ItemClickSupport addTo(RecyclerView view) {
// if there's already an ItemClickSupport attached
// to this RecyclerView do not replace it, use it
ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
if (support == null) {
support = new ItemClickSupport(view);
}
return support;
}
public static ItemClickSupport removeFrom(RecyclerView view) {
ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
if (support != null) {
support.detach(view);
}
return support;
}
public ItemClickSupport setOnItemClickListener(OnItemClickListener listener) {
mOnItemClickListener = listener;
return this;
}
public ItemClickSupport setOnItemLongClickListener(OnItemLongClickListener listener) {
mOnItemLongClickListener = listener;
return this;
}
private void detach(RecyclerView view) {
view.removeOnChildAttachStateChangeListener(mAttachListener);
view.setTag(R.id.item_click_support, null);
}
public interface OnItemClickListener {
void onItemClicked(RecyclerView recyclerView, int position, View v);
}
public interface OnItemLongClickListener {
boolean onItemLongClicked(RecyclerView recyclerView, int position, View v);
}
}
එය ක්රියාත්මක වන ආකාරය (එය කාර්යක්ෂම වන්නේ ඇයි)
මෙම පන්තිය අනුයුක්ත කිරිම මඟින් ක්රියා RecyclerView.OnChildAttachStateChangeListener
කිරීමට RecyclerView
. දරුවෙකු ඇමිණූ විට හෝ වෙන් වූ සෑම අවස්ථාවකම මෙම සවන්දෙන්නන්ට දැනුම් දෙනු ලැබේ RecyclerView
. කේතය මෙය භාවිතා කරන්නේ ටැප් / දිගු ක්ලික් සවන්දෙන්නෙකු දර්ශනයට එකතු කිරීමට ය. බව ශ්රවණය ඇසීමට RecyclerView
සඳහා RecyclerView.ViewHolder
තත්වය අඩංගු.
මෙය වඩාත් කාර්යක්ෂම වන්නේ වෙනත් විසඳුම් වන නිසා එය එක් එක් දර්ශනය සඳහා බහු සවන්දෙන්නන් නිර්මාණය කිරීමෙන් වැළකී සිටින අතර RecyclerView
ඒවා අනුචලනය කරන අතරතුර ඒවා විනාශ කරමින් නිර්මාණය කරයි .
ඔබට තවත් අවශ්ය නම් කේතය අනුවර්තනය කළ හැකිය.
අවසාන ප්රකාශය
ඔබේ ලැයිස්තුවේ සෑම දර්ශනයක්ම ක්ලික් සවන්දෙන්නෙකු ලෙස යෝජනා කිරීමෙන් ඔබේ ඇඩැප්ටරය තුළ එය හැසිරවීම සම්පුර්ණයෙන්ම සුදුසු බව මතක තබා ගන්න.
එය කළ යුත්තේ වඩාත්ම කාර්යක්ෂම දෙය නොවේ (ඔබ දර්ශනයක් නැවත භාවිතා කරන සෑම අවස්ථාවකම ඔබ නව සවන්දෙන්නෙකු නිර්මාණය කරයි) නමුත් එය ක්රියාත්මක වන අතර බොහෝ අවස්ථාවල එය ගැටළුවක් නොවේ.
ක්ලික් කිරීමේ සිදුවීම් පැවරීම ඇඩැප්ටරයේ කාර්යය නොවන නිසා එය උත්සුකයන් වෙන් කිරීමට ද තරමක් විරුද්ධ ය.