私はAndroidアプリケーションを開発しています。これをプレイストアに公開した後、この問題に直面しました。例外java.lang.IndexOutOfBoundsException:不一致が検出されました。無効なビューホルダーアダプターpositionViewHolder
Exception java.lang.IndexOutOfBoundsException: Inconsistency detected.Invalid view holder adapter positionViewHolder{2f9d83c position=11 id=-1, oldPos=-1, pLpos:-1 no parent}
android.support.v7.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition (RecyclerView.java:5297)
android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline (RecyclerView.java:5479)
android.support.v7.widget.GapWorker.prefetchPositionWithDeadline (GapWorker.java:282)
android.support.v7.widget.GapWorker.flushTaskWithDeadline (GapWorker.java:336)
android.support.v7.widget.GapWorker.flushTasksWithDeadline (GapWorker.java:349)
android.support.v7.widget.GapWorker.prefetch (GapWorker.java:356)
android.support.v7.widget.GapWorker.run (GapWorker.java:387)
android.os.Handler.handleCallback (Handler.java:815)
android.os.Handler.dispatchMessage (Handler.java:104)
android.os.Looper.loop (Looper.java:207)
android.app.ActivityThread.main (ActivityThread.java:5737)
java.lang.reflect.Method.invoke (Method.java)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:789)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:679)
私はこの問題について長い時間を検索し、多くのソリューションを適用するが、例外はまだ
を上げた私が塗布された溶液の一つは、カスタムLinearLayoutManagerを作っていた:私のアプリケーションで
public class WrapContentLinearLayoutManager extends LinearLayoutManager {
public WrapContentLinearLayoutManager(Context context) {
super(context);
}
//... constructor
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
try {
super.onLayoutChildren(recycler, state);
setAutoMeasureEnabled(false);
} catch (IndexOutOfBoundsException e) {
Log.e("Error", "IndexOutOfBoundsException in RecyclerView happens");
}
}
public WrapContentLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
setAutoMeasureEnabled(false);
}
public WrapContentLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
setAutoMeasureEnabled(false);
}
@Override
public boolean supportsPredictiveItemAnimations() {
return false;
}
}
依存RecyclerViewでをロードmoreとスワイプで更新する機能
I ロードRecyclerViewに詳しい項目をロードするために
をリフレッシュするために、よりとスワイプするためのWebサービスからデータを取得するためにバレーボールを使用して、バックバレーボール応答のコールの内側に私はArrayListに新しいアイテムを追加し、通知LOAの場合Adapter.UpdateItems
public void updateItems(int positionStart,int itemCount) {
itemsCount = getItemCount();
this.notifyItemRangeInserted(positionStart,itemCount);
}
ため
final int positionStart = list.size() - 1;
final int itemCount = response.length();
for (int i=0;i<response.length();i++)
{
try
{
obj = response.getJSONObject(i);
list.add(new ItemEntry(obj.getInt("Id"),obj.getString("Title").trim()obj.getBoolean("isFavorite"));
} catch (JSONException e) {
e.printStackTrace();
}
if(index == 0)
{
// for first Initialize for adapter
adapter = new MyAdapter(latestEntryList,getActivity());
adapter.setOnItemClickCallBack(mainFragment);
recyclerView.setAdapter(adapter);
}
else
{
// for load more items
recyclerView.post(new Runnable()
{
@Override
public void run()
{
adapter.updateItems(positionStart,itemCount);
}
});
}
}
コード:このようにアダプタdもっと私は以下を行います。 OnRefresh
でpublic void onRefresh() {
listFragment.LatestEntry(0,false);
// 0 the index and False isAppend to list of not
}
LatestEntryためのコードは次のとおりです。
private void LatestEntry(final int index, final boolean isAppend)
{
String customerId = "123";
String uri = String.format(BASE_URL+"/api/Entry/LatestEntry?customerId=%s&index=%s",customerId,index);
JsonArrayRequest LatestEntryJsonArrayRequest = new JsonArrayRequest(Request.Method.GET, uri,
null, new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response)
{
JSONObject obj = new JSONObject();
if(response.length() > 0 && !isAppend)
{
int startPosition = 0;
int preSize;
if(adapter != null)
preSize = adapter.entries.size();
else
preSize = 0;
if(preSize > 0 && EntryList.size() > 0) {
EntryList.clear();
adapter.entries.clear();
adapter.notifyItemRangeRemoved(startPosition, preSize);
}
}
final int positionStart = EntryList.size() - 1;
final int itemCount = response.length();
for (int i=0;i<response.length();i++)
{
try {
obj = response.getJSONObject(i);
list.add(new ItemEntry
(obj.getInt("Id"),obj.getString("Title").trim()
obj.getBoolean("isFavorite"));
} catch (JSONException e) {
e.printStackTrace();
}
}
if(index == 0)
{ // for first Initialize for adapter
adapter = new MyAdapter(latestEntryList,getActivity());
adapter.setOnItemClickCallBack(mainFragment);
recyclerView.setAdapter(adapter);
}
else
{
// for load more items
recyclerView.post(new Runnable()
{
@Override
public void run() {
adapter.updateItems(positionStart,itemCount);
}
});
}
}
setListShownNoAnimation(true);
if(mainFragment.swipeRefreshLayout.isRefreshing())
mainFragment.swipeRefreshLayout.setRefreshing(false);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MyApplication.getAppContext(),error.getMessage(),Toast.LENGTH_LONG);
}
}
);
LatestEntryJsonArrayRequest.setTag("LatestEntry");
KidsSingleton.getInstance().addToRequestQueue(LatestEntryJsonArrayRequest);
}
次の点に注意してください
- Recyclerviewバージョンは次のとおりです。recyclerview-V7:25.3.0
- 私が持っていますViewPagerの3つのRecylerView
- 各ViewPagerにはフラグメントが含まれ、フラグメントにはListFが含まれますRecylerViewとの競合。
- すべてのRecylcrViewに1つのアダプタがあります。
この問題を解決する方法はありますか?
reccyleviewサポートライブラリのバージョンは何ですか? –
私はこのバージョンを使用していますrecyclerview-v7:25.3.0 –
FYI: 'onLayoutChildren()'はここでは問題ありません。スタックトレースはリストに表示されません。 –