1

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);
                }
            }
        }
    }

}
Community
  • 1
  • 1

0 Answers0