问题
Issue
First time it works fine. this app download image from the internet and save into external storage.
I want to make a method when i call the method then it will repopulate the image from external storage and set new adapter to show the all images on PagerView
.
In simple words i want to refresh the pagerview screens view. on app start there is 3 images in sdcard. and when i press button then there is 4 images in sdcard. it should update/refresh the view.
This the custom adapter class
public class CustomSwipeAdapter extends PagerAdapter {
static ImageView i1;
String pdfName;
static Bitmap[] bmp ;
private Context ctx;
private LayoutInflater layoutInflater;
public CustomSwipeAdapter(Context ctx) {
this.ctx =ctx;
}
@Override
public int getCount() {
bmp=Picgraber();
return bmp.length;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return (view==(LinearLayout)object);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
//Picgraber();
layoutInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View item_view = layoutInflater.inflate(R.layout.swipe_layout,container,false);
i1 = (ImageView)item_view.findViewById(R.id.swipeimageview);
TextView t1 = (TextView)item_view.findViewById(R.id.swipetextview);
// i1.setImageResource(images[position]);
i1.setImageBitmap(bmp[position]);
i1.setTag(imagesstr[position]);
t1.setText("image "+ position);
pdfName = String.valueOf(i1.getResources());
Log.d("pdfname", pdfName);
Log.d("position", String.valueOf(position));
container.addView(item_view);
return item_view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((LinearLayout)object);
}
public Bitmap[] Picgraber(){
ArrayList<Bitmap> list = new ArrayList<Bitmap>();
File file= new File("/sdcard/com.shah.tabs/");
File[] folders=file.listFiles();
for(File ff:folders){
File it=new File(file.getPath()+File.separator+ff.getName()+File.separator+"image"+File.separator+ff.getName()+".png");
// Log.w("folder with path",it.getPath());
list.add(BitmapFactory.decodeFile(it.getPath()));
}
Bitmap[] Array = list.toArray(new Bitmap[list.size()]);
return Array;
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
public void update(){
bmp = Picgraber();
this.notifyDataSetChanged();
}
}
This is the onCreate method of the activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_books);
packageFolder = new File(Environment.getExternalStorageDirectory() + File.separator + getApplicationContext().getPackageName());
if (!packageFolder.exists()) {
packageFolder.mkdir();
}
viewPager = (ViewPager) findViewById(R.id.viewpager);
adapter = new CustomSwipeAdapter(this);
viewPager.setAdapter(adapter);
Log.d("curritem", String.valueOf(viewPager.getCurrentItem()));
viewPager.setPageTransformer(true, new ZoomOutSlideTransformer());
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
public void onPageScrollStateChanged(int state) {}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
public void onPageSelected(int position) {
pos = position;
Log.d("onpagechange", String.valueOf(pos));
Log.d("imagename", String.valueOf(CustomSwipeAdapter.i1.getTag()));
}
});
viewPager.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
x1 = event.getX();
y1 = event.getY();
break;
}
case MotionEvent.ACTION_UP: {
x2 = event.getX();
y2 = event.getY();
if (x1 < x2) {
}
if (x1 > x2) {
}
if (y1 < y2) {
}
if (y1 > y2 + 100) {
downtoupswipe();
}
break;
}
}
return false;
}
});
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("file/*");
startActivityForResult(intent, 1);
}
});
}
This the logcat of the application when crash
10-10 11:00:50.388 16816-16816/com.shah.tabs E/InputEventReceiver: Exception dispatching input event.
10-10 11:00:50.389 16816-16816/com.shah.tabs E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback
10-10 11:00:50.390 16816-16816/com.shah.tabs E/MessageQueue-JNI: java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 2, found: 3 Pager id: com.shah.tabs:id/viewpager Pager class: class android.support.v4.view.ViewPager Problematic adapter: class com.shah.tabs.CustomSwipeAdapter
at android.support.v4.view.ViewPager.populate(ViewPager.java:1071)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1025)
at android.support.v4.view.ViewPager.onTouchEvent(ViewPager.java:2114)
at android.view.View.dispatchTouchEvent(View.java:8471)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2399)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2092)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2369)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1719)
at android.app.Activity.dispatchTouchEvent(Activity.java:2742)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2330)
at android.view.View.dispatchPointerEvent(View.java:8666)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4123)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3989)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3680)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3737)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5807)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5781)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5752)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5897)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:143)
at android.os.Looper.loop(Looper.java:122)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
10-10 11:00:50.390 16816-16816/com.shah.tabs D/AndroidRuntime: Shutting down VM
10-10 11:00:50.393 16816-16816/com.shah.tabs E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.shah.tabs, PID: 16816
java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 2, found: 3 Pager id: com.shah.tabs:id/viewpager Pager class: class android.support.v4.view.ViewPager Problematic adapter: class com.shah.tabs.CustomSwipeAdapter
at android.support.v4.view.ViewPager.populate(ViewPager.java:1071)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1025)
at android.support.v4.view.ViewPager.onTouchEvent(ViewPager.java:2114)
at android.view.View.dispatchTouchEvent(View.java:8471)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2399)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2092)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2369)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1719)
at android.app.Activity.dispatchTouchEvent(Activity.java:2742)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2330)
at android.view.View.dispatchPointerEvent(View.java:8666)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4123)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3989)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3680)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3737)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5807)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5781)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5752)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5897)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:143)
at android.os.Looper.loop(Looper.java:122)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
**
Call from activity fab button
**
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
adapter.update();
}
});
回答1:
Using the array of bitmaps have a performance issues. You can use any ImageLoader libs to do display image.
The Universal ImageLoader has methods to display local images
make some changes in this class CustomSwipeAdapter
@Override
public int getCount() {
return imagesstr.length();
}
//add this method
public void setImages(String image[]){
imagesstr = image;
this.notifyDataSetChanged();
}
to display image use the imageLoader as suggested earlier
回答2:
Just take a look at the Exception message you got here. It says:
java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 2, found: 3
It is pretty clear from the Exception message that while refreshing your PagerView, you are adding new images but you are not telling the adapter that the data which it is going to populate has been changed. As a result, the adapter expecting to just populate 2 images find 3 images and your application crashes.
So whenever you add a new image you need to explicitly call adapter.notifyDataSetChanged()
to tell the adpater that a new image has been added which would eventually solve this issue.
来源:https://stackoverflow.com/questions/39952344/how-to-re-populate-the-pagerview-view-using-pageradapter