大量のデータを渡す必要があるため、インテントを使用する代わりに、静的クラスを使用してビューに値を渡そうとしています。時々私はこのエラーを受け取り、主な理由が何であるかを見つけることができませんでした
エラー:-
Java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 101, found: 200
私のポケットベルクラス
public class MemeDetailActivity extends AppCompatActivity implements OnDialogClickListner<Void> {
private ViewPager mPager;
private List<Datum> mList;
private ScreenSlidePagerAdapter pagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_meme_detail);
mList = DataResult.getInstance().getData();
DataResult.getInstance().resetData();
if (mList != null)
startPager(selected_position);
else
Toast.makeText(this, "Error loading data", Toast.LENGTH_SHORT).show();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}
private void startPager(int position) {
pagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(pagerAdapter);
pagerAdapter.notifyDataSetChanged();
mPager.setOffscreenPageLimit(0);
mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
new Interactors(MemeDetailActivity.this).updateView(Util.getAccessToken(), mList.get(position).getId(), new OnFinishListner<ViewsRM>() {
@Override
public void onFinished(ViewsRM result) {
}
@Override
public void onFailed(String msg) {
}
});
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
mPager.setCurrentItem(position);
}
public class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
//todo entry point 3 : showing the image in the viewpager
@Override
public Fragment getItem(int position) {
Fragment fragment = new fragment_mypager_new();
Bundle bundle = new Bundle();
if (frmMyMemes)
bundle.putParcelable("MY_DATA", myList);
bundle.putSerializable("DATA", mList.get(position));
fragment.setArguments(bundle);
return fragment;
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
@Override
public int getCount() {
return mList.size();
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
}
}
私の静的クラス
public class DataResult<T> {
private static DataResult instance;
private List<T> data = null;
protected DataResult() {
}
public static synchronized DataResult getInstance() {
if (instance == null) {
instance = new DataResult();
}
return instance;
}
public List<T> getData() {
return data;
}
public void setData(List<T> data) {
this.data = data;
}
public void resetData() {
data = null;
}
}
アクティビティを呼び出す方法
Intent intent = new Intent(getActivity(), MemeDetailActivity.class);
DataResult.getInstance().setData(mListA);
時々このエラーが発生します。
これが私の提案です:
あなたのDataResult
-> getData()
データのコピーを返します。
DataResult
はシングルトンであり、データを保持します。ビューがデータを取得すると、ビューはDataResult
が保持しているデータ参照を取得します。次に、setData()
はdata
参照を変更します。 IllegalStateExceptionが発生します。
それがうまくいくことを願っています:)
あなたのコードを見てください:
_ @Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
_
このコードは、ビューが変更されたときにビューを更新するために使用されます。 notifyDataSetChanged()
とも呼ばれます
オプションのovverrideメソッドにより、削除できます。
この答えを見てください: ViewPager PagerAdapter not view the update
または、FragmentStatePagerAdapter
をFragmentPagerAdapter
に変更できます
最初にメソッドsetAdapter()
でinitUI()
およびnotifyDataSetChanged
を使用している可能性があります。
次に、メソッドinitData()
でList<?>
データをインスタンス化します。2つのメソッドは、フラグメントの存続期間が異なります。
フラグメントのライフサイクルに関する問題です
次の方法を試してください:
mList=new ArrayList<Datum>();
mList.addAll(DataResult.getInstance().getData());
DataResult.getInstance().resetData();
@Override
public void restoreState(Parcelable state, ClassLoader loader) {}
@Override
public Parcelable saveState() {return null;}
#Add in your adapter after getCount();
DataResult
クラスは必要ないと思います。
コメントによると、データセットを更新しているときにエラーが発生しています。 REST APIまたは別のWebサービスからデータを取得していると思います。次に、APIから取得したデータを一時配列リストに割り当て、新しいデータを取得している間にその一時配列リストを更新しますデータの受信が完了するまで、mListA
変数には触れないでください。APIからのデータの取得が完了したら、使用した一時配列リストをmListA
に1行で直接割り当てます。
mListA = tmpList;
その後、もう一度電話します
mList = mListA;
pagerAdapter.notifyDataSetChanged();
これでエラーが解決します。