每次删除项目时,RecyclerView最后一项都会闪烁

时间:2017-09-18 02:31:22

标签: android android-recyclerview android-contentprovider android-contentresolver android-cursorloader

我正在使用带有RecyclerView的游标加载器,除了每次从RecyclerView中删除项目时,其他一切都很好,最后一项闪烁,就像这样

last item blinks

我的删除代码是

public void deleteData(long id){
    Uri uri = ContentUris.withAppendedId(URI, id);
    getContentResolver().delete(uri, null, null);
}
刷卡上的

代码:

deleteData(viewHolder.getItemId());

请注意,我有另一个使用相同RecyclerAdapterContentProvider和布局代码的活动,即使大多数实现和方法方法都是相同的,但是一个活动完美无任何闪烁,所以对我来说这是一个非常奇怪的情况。

是否有可能导致此问题的具体原因?我已经尝试过禁用像

这样的动画
recyclerView.getItemAnimator().setChangeDuration(0);

((DefaultItemAnimator) recyclerViewObject.getItemAnimator()).setSupportsChangeAnimations(false);

但这些都没有用,更不用说我确实希望动画能够发挥作用。

修改:上传断点:

的onCreate:

  

“main @ 4668”prio = 5 tid = 0x2 nid = NA runnable       java.lang.Thread.State:在com.jackz314.todo.HistoryActivity.onCreateLoader(HistoryActivity.java:803)的RUNNABLE       在   android.support.v4.app.LoaderManagerImpl.createLoader(LoaderManager.java:539)       在   android.support.v4.app.LoaderManagerImpl.createAndInstallLoader(LoaderManager.java:548)at at   android.support.v4.app.LoaderManagerImpl.initLoader(LoaderManager.java:603)       在   com.jackz314.todo.HistoryActivity.displayAllNotes(HistoryActivity.java:394)       在   com.jackz314.todo.HistoryActivity.deleteExpiredNotes(HistoryActivity.java:767)       在   com.jackz314.todo.HistoryActivity.onCreate(HistoryActivity.java:129)
  在android.app.Activity.performCreate(Activity.java:6975)at   android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)       在   android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)       在   android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)       在android.app.ActivityThread.-wrap11(ActivityThread.java:-1)处   android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1593)
  在android.os.Handler.dispatchMessage(Handler.java:105)at   android.os.Looper.loop(Looper.java:164)at   android.app.ActivityThread.main(ActivityThread.java:6541)at   java.lang.reflect.Method.invoke(Method.java:-1)at   com.android.internal.os.Zygote $ MethodAndArgsCaller.run(Zygote.java:240)       在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

onDelete(删除项目):

  

“main @ 4668”prio = 5 tid = 0x2 nid = NA runnable java.lang.Thread.State:   RUNNABLE在   com.jackz314.todo.HistoryActivity.deleteData(HistoryActivity.java:791)       在   com.jackz314.todo.HistoryActivity $ 4.onSwiped(HistoryActivity.java:434)       在   android.support.v7.widget.helper.ItemTouchHelper $ 4.run(ItemTouchHelper.java:686)       在android.os.Handler.handleCallback(Handler.java:789)at   android.os.Handler.dispatchMessage(Handler.java:98)at   android.os.Looper.loop(Looper.java:164)at   android.app.ActivityThread.main(ActivityThread.java:6541)at   java.lang.reflect.Method.invoke(Method.java:-1)at   com.android.internal.os.Zygote $ MethodAndArgsCaller.run(Zygote.java:240)       在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

希望那些帮助

修改:经过一番调查后,我发现最后一项实际上没有闪烁,似乎RecyclerView首先改变了它的长度/大小,切断了一个部分与删除的项目具有相同的大小(删除),以便最后一项(取决于已删除项目的大小)暂时不可见,然后RecyclerView删除应该是的项目在开头删除。我还在努力,试图弄清楚是不是因为我把订单搞砸了,或者是其他原因。

6 个答案:

答案 0 :(得分:1)

终于搞定了!

又一个愚蠢的错误,它根本不复杂,我一直在想,为什么我只在这个活动上遇到这个问题,而不是我以前的问题,我突然意识到布局在这两个活动是不同的,结果我将RecyclerView的高度设置为wrap_content,所以我想发生了什么,布局告诉系统将内容包装在{{{ 1}},当您删除某个项目时,它在技术上已不再存在,因此,即使我有已删除项目的动画,该项目也会立即从布局的级别删除,即&#39 ;为什么Android似乎首先调整RecyclerView的高度,然后删除该项,实际发生的是,因为RecyclerView设置为RecyclerView,它会删除删除后立即查看(项目)的位置,而不是动画后的位置,以及为什么它看起来像是闪烁。

无论如何,解决方案只是将wrap_content的高度从RecyclerView更改为任何其他值,如果您像我一样使用wrap_content,只需更改高度为ConstraintLayout,然后将0dp约束为其他内容或边缘。

感谢所有试图帮助我解决问题的人,我承认这是我遇到过的最愚蠢而令人沮丧的问题之一。

我相信其他人也会遇到同样的问题,所以请去检查身高是否设为RecyclerView

答案 1 :(得分:0)

将断点放在数据对象上,该对象与RecyclerViewAdapter绑定并检查数据是否闪烁。在这种情况的大多数情况下,我意识到数据可能会受到影响并使视图变化无法控制。因为我不知道你如何处理数据,所以我无法为你提供更详细的答案。

答案 2 :(得分:0)

您是否尝试过,禁用动画?

adapter.setHasStableIds(true);
recyclerView.setItemAnimator(null);

答案 3 :(得分:0)

Jackz下面的代码在DetailsActivity中,它有一个btnDelete,它会触发并转到DBHelper并删除记录并返回到DetailsActivity,然后调用ListActivity从列表中删除该项目,基于位置NOT记录ID < / p>

   private void addListenerOnButtonDelete() {
    btnDelete.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            // Calls the Method deleteDBRow in DatabaseHelper
            // which acts on the TABLE_INFO to remove a record by getting the record ID
            helper.deleteDBRow(String.valueOf(dbList.get(position).getID()));
            ListActivity.removeListRow(position);
            // Code line above calls Method in ListActivity to notify recycler view of changes
            // NOTICE the List keeps items by position not ID <== READ
            etWebSite.setText("");
            etUN.setText("");
            etPW.setText("");
            etSecQuestion.setText("");
            etSecAnswer.setText("");
            etNotes.setText("");

            Intent intent = new Intent(DetailsActivity.this, ListActivity.class);
            startActivity(intent);
        }
    });
}

以下是ListActivity中与适配器对话的代码

    // This method is called from DetailsActivity and notifies Recycler View that the DB was changed
// and the method makes the same changes to the Recycler View kind of a sync of DB and Recycler View
public static void removeListRow(int position) {
    dbList.remove(position);
    mAdapter.notifyItemRemoved(position);
    mAdapter.notifyItemRangeChanged(position, dbList.size());
}

答案 4 :(得分:0)

我和你一样陷入困境。我相信问题是CursorLoader每次从数据库中删除时都会重新启动,因此onLoadFinished每次都会触发并交换游标。

问题可以解决&#34;如果我们将数据从游标加载到List中并将其传递给适配器。不过,我觉得这是一种解决方法,而不是一个真正的解决方案。

答案 5 :(得分:0)

我完全有同样的问题,这让我发疯。

您的解决方案在我的情况下不起作用,可能是因为我的RecyclerViewer位于LinearLayout内?

到目前为止,我发现的唯一解决方法是禁用这样的动画

cardRecyclerView.itemAnimator = null

但是我真的很想重新启用动画,因为没有动画就有点断断续续了。

这是我的布局,是否有人想避免在取出卡后最后一项闪烁?预先谢谢你

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/mainLayout"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:fitsSystemWindows="true"
              android:layout_height="wrap_content">
    <fragment
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:name="com.bendk97.platenumber.activities.main.Toolbar"/>
    <fragment
            android:id="@+id/search_bar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:name="com.bendk97.platenumber.activities.main.SearchBar"/>
    <ProgressBar
            style="@style/Widget.AppCompat.ProgressBar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:indeterminateTint="@android:color/white"
            android:id="@+id/progressBar" android:visibility="invisible"/>
    <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    </android.support.v7.widget.RecyclerView>
</LinearLayout>
相关问题