例如:我创建了一个fragmetn,在其中逐个添加5个视图并替换另一个片段然后反压并打开具有5个动态视图的相同片段但是当我将从视图寻呼机中删除任何特定视图时应用程序将崩溃抛出异常:java.lang.IllegalStateException:应用程序的PagerAdapter在不调用PagerAdapter#notifyDataSetChanged的情况下更改了适配器的内容!预期的适配器项目数:2,找到:1寻呼机ID:寻呼机寻呼机类:类android.support.v4.view.ViewPager有问题的适配器:类
我的ViewPagerAdapter:
public class DynamicPagerAdapter extends PagerAdapter {
// This holds all the currently displayable views, in order from left to right.
private ArrayList<View> views = new ArrayList<View>();
private List<LatLng> dropList = new ArrayList<>();
private EditableListener editableListener;
public DynamicPagerAdapter(EditableListener editableListener) {
this.editableListener = editableListener;
}
//-----------------------------------------------------------------------------
// Used by ViewPager. "Object" represents the page; tell the ViewPager where the
// page should be displayed, from left-to-right. If the page no longer exists,
// return POSITION_NONE.
@Override
public int getItemPosition(Object object) {
int index = views.indexOf(object);
if (index == -1)
return POSITION_NONE;
else
return index;
}
//-----------------------------------------------------------------------------
// Used by ViewPager. Called when ViewPager needs a page to display; it is our job
// to add the page to the container, which is normally the ViewPager itself. Since
// all our pages are persistent, we simply retrieve it from our "views" ArrayList.
@Override
public Object instantiateItem(ViewGroup container, int position) {
View v = views.get(position);
container.addView(v);
return v;
}
//-----------------------------------------------------------------------------
// Used by ViewPager. Called when ViewPager no longer needs a page to display; it
// is our job to remove the page from the container, which is normally the
// ViewPager itself. Since all our pages are persistent, we do nothing to the
// contents of our "views" ArrayList.
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(views.get(position));
}
//-----------------------------------------------------------------------------
// Used by ViewPager; can be used by app as well.
// Returns the total number of pages that the ViewPage can display. This must
// never be 0.
@Override
public int getCount() {
return views.size();
}
//-----------------------------------------------------------------------------
// Used by ViewPager.
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
//-----------------------------------------------------------------------------
// Add "view" to right end of "views".
// Returns the position of the new view.
// The app should call this to add pages; not used by ViewPager.
public int addView(View v) {
return addView(v, views.size());
}
//-----------------------------------------------------------------------------
// Add "view" at "position" to "views".
// Returns position of new view.
// The app should call this to add pages; not used by ViewPager.
public int addView(View v, int position) {
views.add(position, v);
return position;
}
//-----------------------------------------------------------------------------
// Removes "view" from "views".
// Retuns position of removed view.
// The app should call this to remove pages; not used by ViewPager.
public int removeView(ViewPager pager, View v) {
return removeView(pager, views.indexOf(v));
}
//-----------------------------------------------------------------------------
// Removes the "view" at "position" from "views".
// Retuns position of removed view.
// The app should call this to remove pages; not used by ViewPager.
public int removeView(ViewPager pager, int position) {
// ViewPager doesn't have a delete method; the closest is to set the adapter
// again. When doing so, it deletes all its views. Then we can delete the view
// from from the adapter and finally set the adapter to the pager again. Note
// that we set the adapter to null before removing the view from "views" - that's
// because while ViewPager deletes all its views, it will call destroyItem which
// will in turn cause a null pointer ref.
pager.setAdapter(null);
views.remove(position);
pager.setAdapter(this);
pager.setCurrentItem(position, true);
return position;
}
//-----------------------------------------------------------------------------
// Returns the "view" at "position".
// The app should call this to retrieve a view; not used by ViewPager.
public View getView(int position) {
return views.get(position);
}
// Other relevant methods:
// finishUpdate - called by the ViewPager - we don't care about what pages the
// pager is displaying so we don't use this method.
public boolean isContaint(int position) {
try {
views.get(position);
return true;
} catch (IndexOutOfBoundsException e) {
return false;
}
}
public void addLocation(LatLng latLng, AppCompatEditText activeEditText) {
if (activeEditText == null)
return;
if (activeEditText.getTag() != null) {
LatLng lng = (LatLng) activeEditText.getTag();
int i = dropList.indexOf(lng);
if (i > -1) {
dropList.set(i, latLng);
} else
dropList.add(latLng);
} else
dropList.add(latLng);
activeEditText.setTag(latLng);
}
public void removeLocation(AppCompatEditText activeEditText) {
if (activeEditText.getTag() != null) {
LatLng lng = (LatLng) activeEditText.getTag();
int i = dropList.indexOf(lng);
if (i > -1) {
dropList.remove(i);
}
editableListener.notifyMap();
}
}
public List<LatLng> getDropList() {
return dropList;
}
public void doneWithThis(ViewPager viewPager, AppCompatEditText editText,Fragment fragment) {
if (editText != null) {
int currentItem = viewPager.getCurrentItem();
if (currentItem == views.size() - 1)
createNewView(viewPager,fragment);
editText.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.remove_loc, 0);
editableListener.hideKeyBoard();
editText.clearFocus();
}
}
public void createNewView(final ViewPager viewPager, final Fragment fragment) {
final View v = LayoutInflater.from(viewPager.getContext()).inflate(R.layout.address_editext_layout, null);
final int pageIndex = addView(v);
v.setTag(pageIndex);
final AppCompatEditText editText = (AppCompatEditText) v.findViewById(R.id.editTextTo);
final View toLine = v.findViewById(R.id.fromLine);
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
boolean isFocused;
@Override
public void onFocusChange(View view, boolean b) {
View currentView = getView(viewPager.getCurrentItem());
editableListener.isInEditMode(editText, b);
if (currentView == v) {
if (b) {
Intent ii = new Intent(fragment.getActivity(), LocationSearchActivityNew.class);
fragment.getActivity().startActivityForResult(ii, Constant.DROPOFF_REQUEST);
/* AnimationUtil.scale(editText, true, new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
isFocused = true;
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
AnimationUtil.visible(toLine);*/
} else {
/*AnimationUtil.scale(editText, false, new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
isFocused = false;
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
AnimationUtil.inVisible(toLine);*/
}
} else {
if (b) {
//editText.clearFocus();
int i = views.indexOf(v);
if (i != -1)
viewPager.setCurrentItem(i, true);
if (!isFocused) {
/* AnimationUtil.scale(editText, true, new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
isFocused = true;
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
AnimationUtil.visible(toLine);*/
}
} else {
if (isFocused) {
/* AnimationUtil.scale(editText, false, new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
isFocused = false;
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
AnimationUtil.inVisible(toLine);*/
}
}
}
}
});
editText.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
final int DRAWABLE_RIGHT = 2;
if (event.getAction() == MotionEvent.ACTION_UP) {
int actionX = (int) event.getX();
int actionY = (int) event.getY();
Rect bounds;
Drawable drawableRight = editText.getCompoundDrawables()[DRAWABLE_RIGHT];
if (event.getRawX() >= (editText.getRight() - drawableRight.getBounds().width()) && event.getRawX() <= (editText.getWidth() + drawableRight.getBounds().width() + 50)) {
if (editText.getTag() != null) {
removeLocation(editText);
removeView(viewPager, v);
notifyDataSetChanged();
}
return true;
}
}
return false;
}
});
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
editableListener.performSearch(editText.getText());
}
});
notifyDataSetChanged();
}
public interface EditableListener {
void isInEditMode(AppCompatEditText editText, boolean b);
void performSearch(CharSequence charSequence);
void hideKeyBoard();
void notifyMap();
}
}
从我的片段中添加了动态视图:
if(dynamicPagerAdapter==null) {
dynamicPagerAdapter = new DynamicPagerAdapter(this);
pager.setAdapter(dynamicPagerAdapter);
dynamicPagerAdapter.createNewView(pager, HomeFragmentNew.this);
pager.setOffscreenPageLimit(3);
}else{
pager.setAdapter(dynamicPagerAdapter);
dynamicPagerAdapter.notifyDataSetChanged();
}
}
logcat的: java.lang.IllegalStateException:应用程序的PagerAdapter在不调用PagerAdapter#notifyDataSetChanged的情况下更改了适配器的内容!预期的适配器项目数:2,找到:1 Pager id:packagename:id / addressPager Pager class:class android.support.v4.view.ViewPager有问题的适配器:class DynamicPagerAdapter 在android.support.v4.view.ViewPager.populate(ViewPager.java:1134) 在android.support.v4.view.ViewPager.populate(ViewPager.java:1083) 在android.support.v4.view.ViewPager $ 3.run(ViewPager.java:272) 在android.view.Choreographer $ CallbackRecord.run(Choreographer.java:767) 在android.view.Choreographer.doCallbacks(Choreographer.java:580) 在android.view.Choreographer.doFrame(Choreographer.java:549) 在android.view.Choreographer $ FrameDisplayEventReceiver.run(Choreographer.java:753) 在android.os.Handler.handleCallback(Handler.java:739) 在android.os.Handler.dispatchMessage(Handler.java:95) 在android.os.Looper.loop(Looper.java:135) 在android.app.ActivityThread.main(ActivityThread.java:5254) at java.lang.reflect.Method.invoke(Native Method) 在java.lang.reflect.Method.invoke(Method.java:372) 在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:903) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)