【问题标题】:Removing a SelectionTracker Observer删除 SelectionTracker 观察者
【发布时间】:2020-08-09 14:06:30
【问题描述】:

在我的代码中,当单击回收器视图中的一个项目时,适配器会被替换为一个新的。在此之后,为新适配器创建一个新的跟踪器和观察器。但是在长按时,会调用先前的观察者。我想知道是否可以从跟踪器中删除观察者或从回收器视图中删除项目触摸侦听器。

String id = "track" + mAdapter.getItemId(0);
    if(mAdapter.getTracker() != null) mTracker = mAdapter.getTracker();
    else {
        mTracker = new DefaultSelectionTracker.Builder<>(id, mRecyclerView,
                new MediaKeyProvider(mRecyclerView), setLookup(), StorageStrategy.createLongStorage())
                .withSelectionPredicate(SelectionPredicates.<Long>createSelectAnything())
                .build();

        mAdapter.passTracker(mTracker);
    }
    ((MainActivity) requireActivity()).observeFiles(mTracker, id);

这是创建跟踪器的代码

public class MediaKeyProvider extends ItemKeyProvider {

private RecyclerView mRecyclerView;

public MediaKeyProvider(RecyclerView rv){
    super(ItemKeyProvider.SCOPE_MAPPED);
    mRecyclerView = rv;
}
@Nullable
@Override
public Object getKey(int position) {
    long itemId = mRecyclerView.getAdapter().getItemId(position);
    return itemId == -1 ? RecyclerView.NO_ID : itemId;
}

@Override
public int getPosition(@NonNull Object key) {

    VideoFileAdapter.ViewHolder vh = (VideoFileAdapter.ViewHolder)  mRecyclerView.findViewHolderForItemId((Long) key);
    return vh == null ? RecyclerView.NO_POSITION : vh.getAdapterPosition();
}
}

媒体密钥提供者

【问题讨论】:

    标签: android android-recyclerview androidx


    【解决方案1】:

    我遇到了同样的问题:仅使用一个回收器视图,仅将适配器更改为另一个适配器,并对某些适配器使用 SelectionTracker,但并非对所有适配器都使用。不知何故,旧的选择跟踪器在构建后仍在干扰。 构建选择跟踪器时,会在回收器视图和带有侦听器的选择跟踪器之间创建一个链接。如果您有侦听器,则可以使用 removeOnItemTouchListener 将其删除。但你没有。所以这是我的解决方案(在 Kotlin 中,抱歉):

    1. 每次创建适配器时都使用新的回收站视图。但我不喜欢这个。
    2. 清空回收站视图中的属性“mOnItemTouchListeners”。当 mOnItemTouchListeners 是回收站视图的私有成员时,如何做到这一点?我在 Kotlin 中使用扩展方法。
        import androidx.recyclerview.widget.RecyclerView
        
        // This method use reflection to access a private member of a class
        // variableName : Name of the member to access
        fun <T : Any> T.getPrivateProperty(variableName : String) : Any?
        {
          return javaClass.getDeclaredField(variableName).let { field ->
            field.isAccessible = true
            return@let field.get(this)
          }
        }
        
        // This method access the private member mOnItemTouchListeners from recyclerview and remove all the listener.
        // This method is created as an extension of the class RecyclerView
        fun RecyclerView.removeAllTouchListener()
        {
          val listenerArray = this.getPrivateProperty("mOnItemTouchListeners") as? java.util.ArrayList<RecyclerView.OnItemTouchListener>
          listenerArray?.clear()
        }
    

    我可以在更改适配器之前像这样调用此方法,最好是在前一个适配器使用 selectionTracker 时:

    mRecyclerView.removeAllTouchListener()
    

    mRecyclerView 是我班级的成员,其中包含我拥有的唯一一个 RecyclerView。

    private lateinit var mRecyclerView : RecyclerView
    

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多