I´m using a custom scroll view that load several images like a android view page. On this view i have already loaded the current page, and left, right pages of document that i want to show, so i´m using only three bitmaps that are reused by inBitmap option when scrolling. The problem comes when i try to change scroll direction quickly. In this case, sometimes pages are in wrong secuence. I´m pretty sure that is a concurrence problem with the threads that load images but i´m not able to fix it.
Searching others post, i´ve found something similar on [BitmapFactory.Options.inBitmap causes tearing when switching ImageView bitmap often][1]
[1]: BitmapFactory.Options.inBitmap causes tearing when switching ImageView bitmap often Help please!. My code:
private static final int WINDOW_SIZE = 3;
private Bitmap mReusableBitmapFront;
private Bitmap mReusableBitmapLeft;
private Bitmap mReusableBitmapRight;
private Bitmap[] mReusableBitmaps = {
mReusableBitmapLeft, mReusableBitmapFront, mReusableBitmapRight
};
private LinearLayout mContentContainer;
private void initPresentationContent() {
for (int page = 0; page < numPages; page++) {
ImageView iView = new ImageView(mContext);
LayoutParams params = new LayoutParams(DEFAULT_WITDH, DEFAULT_HEIGHT);
iView.setLayoutParams(params);
// Init first 3 pages
if (page < WINDOW_SIZE) {
LoadPageAsynTask loadPageTask = new LoadPageAsynTask(page);
loadPageTask.execute();
}
iView.setTag(page);
mContentContainer.addView(iView);
}
}
class LoadPageAsynTask extends AsyncTask<Void, Void, Boolean> {
int mPage;
public LoadPageAsynTask(int page) {
mPage = page;
}
@Override
protected Boolean doInBackground(Void... params) {
String pagePath = CONTENT_PATH + (mPage) + ".jpg";
decodeSampledBitmapFromFile(pagePath, DEFAULT_WITDH, DEFAULT_HEIGHT, mPage % WINDOW_SIZE);
return true;
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
// Set page to viewer
((ImageView) mContentContainer.getChildAt(mPage)).setImageBitmap(mReusableBitmaps[mPage
% WINDOW_SIZE]);
}
}
public void decodeSampledBitmapFromFile(String pagePath, int reqWidth,
int reqHeight, int pos) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pagePath, options);
options.inMutable = true;
options.inBitmap = mReusableBitmaps[pos];
options.inSampleSize = 1;
options.inJustDecodeBounds = false;
mReusableBitmaps[pos] = BitmapFactory.decodeFile(pagePath, options);
}
@Override
protected void onScrollChanged(int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
super.onScrollChanged(scrollX, scrollY, oldScrollX, oldScrollY);
mCurrentScrollY = scrollY;
mScrollPage = (int) ((scrollY + (mPageHeight * ADVANCE_PAGE_FACTOR))
/ (mContentContainer.getHeight() / numPages));
// Next page
if (mCurrentPage < mScrollPage) {
mCurrentPage = mScrollPage;
if (mContentContainer.getChildAt(mCurrentPage + 1) != null) {
if (((ImageView) mContentContainer.getChildAt(mCurrentPage + 1)).getDrawable() == null) {
LoadPageAsynTask loadPageTask = new LoadPageAsynTask(mCurrentPage + 1);
loadPageTask.execute();
}
}
}
// Previous page
else if (mCurrentPage > mScrollPage) {
mCurrentPage = mScrollPage;
if (mContentContainer.getChildAt(mCurrentPage - 1) != null) {
if (((ImageView) mContentContainer.getChildAt(mCurrentPage - 1)).getDrawable() == null) {
LoadPageAsynTask loadPageTask = new LoadPageAsynTask(mCurrentPage - 1);
loadPageTask.execute();
// Remove unused child
if (mContentContainer.getChildAt(mCurrentPage + (WINDOW_SIZE - 1)) != null) {
Log.d(TAG, "remove child on pos: " + (mCurrentPage + (WINDOW_SIZE - 1)));
((ImageView) mContentContainer.getChildAt(mCurrentPage + (WINDOW_SIZE - 1)))
.setImageDrawable(null);
}
}
}
}
}