2

我有一个视图寻呼机,其中每个页面都是一个自定义视图(...而不是 a Fragment),我使用LayoutInflator. 每个自定义视图都有一个ImageView内部,使用该Glide库填充来自网络的图像。

我的任务是当用户滚动时,每次他更改页面时都会抛出视图寻呼机,我需要检索Bitmap正在填充当前显示的页面ImageView

我尝试OnPageChangeListener在视图寻呼机上使用 set 并使用该onPageSelected方法获取当前视图,使用该viewPager.getChildAt()方法或viewPager.getFocusedChild().

这是代码:

活动:

public class TimelineMomentActivity extends ActivityBase implements ViewPager.OnPageChangeListener, View.OnClickListener,
    TimelineCommentsGetRequest.Callback, CreativeHandler.CreativeHandleCallback {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    AppInstance.sharedInstance().getBus().register(this);

    mShouldSaveToDB = AppInstance.sharedInstance().isSelf();
    mStory = getIntent().getParcelableExtra(StoryDB.KEY_NAME);

    final String storyID = getIntent().getStringExtra(KEY_STORY_ID);
    final String momentID = getIntent().getStringExtra(KEY_MOMENT_ID);
    mSelectedIndex = getIntent().getIntExtra(ARG_SELECTED_INDEX, 0);

    if (!mShouldSaveToDB) {
        if (mStory == null) {
            sendRequest(storyID, momentID);
        } else {
            mMoments = mStory.getMoments();
            setViewPager();
        }
    } else {
        if (mStory != null) {
            mStoryDB = DBManager.getStory(mStory.getID());
        } else {
            mStoryDB = DBManager.getStory(storyID);
        }
        if (mStoryDB == null) {
            sendRequest(storyID, momentID);
        } else {
            setGlobalDataWithStoryDB();
            setViewPager();
        }
    }

    mCreativeHandler = new CreativeHandler(this, this);

    File cacheDir = Glide.getPhotoCacheDir(this, MyGlideModule.DISK_IMAGE_CACHE_NAME);
    File[] filesList = cacheDir.listFiles();
    for (File cachedFile : filesList) {
        Log.d(TAG, "cachedFileName = " + cachedFile.getName() + " ,path = " + cachedFile.getAbsolutePath());
    }
}

@Override
public Toolbar setToolbar() {
    Toolbar mToolbar = (Toolbar) findViewById(R.id.mToolbar);
    mToolbar.setBackgroundColor(getResources().getColor(R.color.black_color));
    mToolbar.setVisibility(View.VISIBLE);
    return mToolbar;
}

@Override
public void findViews() {
    setContentView(R.layout.timeline_moment_activity);
    mVp = (HackyViewPager) findViewById(R.id.mVp);
    mTvName = (TextView) findViewById(R.id.mTvName);
    mTvContent = (TextView) findViewById(R.id.mTvVpContent);
    mTvDate = (TextView) findViewById(R.id.mTvUsername);
    mTvNumberOfLikes = (TextView) findViewById(R.id.mTvNumberOfLikes);
    mBtnLike = (ImageView) findViewById(R.id.mBtnLike);
    mTvNumberOfComments = (TextView) findViewById(R.id.mTvNumberOfComments);
    mBtnComments = (ImageView) findViewById(R.id.mBtnComments);
    mTvNumberOfShares = (TextView) findViewById(R.id.mTvNumberOfShares);
    mBtnShare = (ImageView) findViewById(R.id.mBtnShare);

    mBtnLike.setOnClickListener(this);
    mTvNumberOfLikes.setOnClickListener(this);

    mBtnShare.setOnClickListener(this);
    mTvNumberOfShares.setOnClickListener(this);

    mBtnComments.setOnClickListener(this);
    mTvNumberOfComments.setOnClickListener(this);
}

…..

private void setGlobalDataWithStoryDB () {
    if (mStoryDB == null) {
        return;
    }
    mMomentsDB = mStoryDB.getMoments();
    mStory = mStoryDB.converter();
    mMoments = mStory.getMoments();
}

// MARK: View Pager

private void setViewPager() {
    mAdapter = new TimelineMomentPagerAdapter(this, mMoments, mStoryDB);
    mVp.setOffscreenPageLimit(-1);
    mVp.addOnPageChangeListener(this);
    mVp.setAdapter(mAdapter);
    mVp.setCurrentItem(mSelectedIndex);
}

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    if (mMoments.isEmpty()) {
        return;
    }

    /*View currentView = mVp.getChildAt(position);
    if (currentView != null) {
        mAdapter.setBitmap(currentView);
    } else {
        currentView = mVp.getFocusedChild();
        if (currentView != null) {
            mAdapter.setBitmap(currentView);
        }
    }*/

    mSelectedIndex = position;
    final MomentPojo moment = mMoments.get(position);

    if (getSupportActionBar() != null)
        getSupportActionBar().setTitle(mStory.getTitle() + " " + (position + 1) + "/" + mMoments.size());

    mTvNumberOfShares.setText(""); // TODO: No API for number of shares

    handleLikeState(moment);
    handleComments(moment);
    mTvName.setText(moment.getOwnerName());
    if (moment.getTimestamp() != null) {
        mTvDate.setText(Utility.timestampToDateString(moment.getTimestamp()));
    } else {
        mTvDate.setVisibility(View.INVISIBLE);
    }

    if (moment.getTitle().equals("")) {
        mTvContent.setVisibility(View.GONE);
    } else {
        mTvContent.setVisibility(View.VISIBLE);
        mTvContent.setText(moment.getTitle());
    }
}

@Override
public void onPageSelected(int position) {
    View currentView = mVp.getChildAt(1);
    if (currentView != null) {
        mAdapter.setBitmap(currentView);
    } else {
        currentView = mVp.getFocusedChild();
        if (currentView != null) {
            mAdapter.setBitmap(currentView);
        }
    }
}

@Override
public void onPageScrollStateChanged(int state) {
}

private void handleComments(MomentPojo moment) {
    final int comments = Integer.parseInt(moment.getCommentsNumber());
    if (comments > 0) {
        mTvNumberOfComments.setText(Utility.showNumInNumK(comments));
    } else {
        mTvNumberOfComments.setText("");
    }
}

private void handleLikeState(MomentPojo moment) {
    if (moment.wasLiked()) {
        mBtnLike.setImageResource(R.drawable.ic_favorite_clicked);
    } else {
        mBtnLike.setImageResource(R.drawable.ic_favorite_unclicked);
    }

    final int likes = Integer.parseInt(moment.getLikesNumber());
    if (likes > 0) {
        mTvNumberOfLikes.setText(Utility.showNumInNumK(likes));
    } else {
        mTvNumberOfLikes.setText("");
    }
}

// MARK: OnClick and OnClick actions

@Override
public void onClick(View v) {
    final MomentPojo moment = mMoments.get(mSelectedIndex);
    if (v == mBtnComments || v == mTvNumberOfComments) {
        actionComment(mMoments.get(mSelectedIndex).getID());
    } else if (v == mBtnLike || v == mTvNumberOfLikes) {
        actionLike(moment);
    } else if (v == mBtnShare || v == mTvNumberOfShares) {
        actionShare();
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent result) {
    mCreativeHandler.onActivityResult(requestCode, resultCode, result);
    if (resultCode == RESULT_OK) {
        switch (requestCode) {
            case Crop.REQUEST_PICK:
                beginCrop(result.getData());
                break;

            case Crop.REQUEST_CROP:
                handleEdit(resultCode, result, cropFileUri);
                break;
        }

    }
    super.onActivityResult(requestCode, resultCode, result);
}

private void actionShare() {
    MomentPojo momentPojo = mMoments.get(mVp.getCurrentItem());
    MomentOptions.actionShare(this, momentPojo);
}

private void actionComment(String momentID) {
    ProgressBarClass.startLoading(this);
    new TimelineCommentsGetRequest(momentID, this);
}

private void actionLike(MomentPojo moment) {
    new LinkerLikePostRequest(LinkerPojo.KEY_SOURCE_TYPE_MOMENT, moment.getID(), new LinkerLikePostRequest.Callback() {
        @Override
        public void onErrorResult(String err) {
            // TODO: handle error
        }
    });
    Utility.d("like state: " + moment.wasLiked());
    final int likes = Integer.parseInt(moment.getLikesNumber());
    if (moment.wasLiked()) {
        moment.setWasLiked(false);
        moment.setLikesNumber((likes - 1) + "");
        mBtnLike.setImageResource(R.drawable.ic_favorite_unclicked);
    } else {
        moment.setWasLiked(true);
        moment.setLikesNumber((likes + 1) + "");
        mBtnLike.setImageResource(R.drawable.ic_favorite_clicked);
    }
    handleLikeState(moment);

    if (mShouldSaveToDB) {
        MomentDB momentDB = mMomentsDB.get(mSelectedIndex);
        if (momentDB.wasLiked()) {
            momentDB.setWasLiked(false);
            momentDB.setLikesNumber((likes - 1) + "");
        } else {
            momentDB.setWasLiked(true);
            momentDB.setLikesNumber((likes + 1) + "");
        }
        momentDB.save();
    }

    mMoments.set(mSelectedIndex, moment);
    AppInstance.sharedInstance().getBus().post(new TimelineBusMomentChanged(moment, TimelineBusMomentChanged.KEY_STATE_LIKED));

}

@Override
public void onFinishedImageEditing(Uri outputFilePath) {
    handleEdit(RESULT_OK, null, outputFilePath);
}

// MARK: Comments
@Override
public void onMomentResult(ArrayList<CommentPojo> comments) {
    final LinkerPojo pojo = new LinkerPojo(mMoments.get(mSelectedIndex));
    ProgressBarClass.dismissLoading();
    CommentsActivity.setInstance(this, pojo, comments);
}

@Override
public void onErrorResult(String err) {
    ProgressBarClass.dismissLoading();
    MyToast.makeText(getString(R.string.gen_Something_went_wrong), MyToast.KEY_TYPE_RED).show();
}

// MARK: Settings

private class SettingsDialog implements ImageRotatePutRequest.Callback {

    private MomentDB mMomentDB;
    private ArrayList<String> mOptions;

    public SettingsDialog(MomentDB momentDB) {
        this.mMomentDB = momentDB;

        final String type = momentDB.getType();
        setOptions(type);
        createDialog();
    }

    private void setOptions(String type) {
        mOptions = new ArrayList<>();
        switch (type) {
            case TimelineUtils.KEY_TYPE_IMAGE:
                mOptions.add(getString(R.string.rotate_left));
                mOptions.add(getString(R.string.rotate_right));
                //mOptions.add(getString(R.string.timeline_moment_crop));
                mOptions.add(getString(R.string.timeline_moment_edit));
                break;

            case TimelineUtils.KEY_TYPE_TEXT:
                break;

            case TimelineUtils.KEY_TYPE_LINK:
                break;

            case TimelineUtils.KEY_TYPE_VIDEO:
                break;
        }
        mOptions.add(getString(R.string.gen_Delete));
    }

    private void createDialog() {
        final ListViewDialog dialog = new ListViewDialog(TimelineMomentActivity.this);
        dialog.setOnItemClickListener(mOptions, new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int i, long id) {
                final String option = mOptions.get(i);

                if (option.equals(getString(R.string.gen_Delete))) {
                    actionDelete();
                } else if (option.equals(getString(R.string.rotate_left))) {
                    actionRotate(false);
                } else if (option.equals(getString(R.string.rotate_right))) {
                    actionRotate(true);
                } /*else if (option.equals(getString(R.string.timeline_moment_crop))) {
                    actionCrop();
                }*/ else if (option.equals(getString(R.string.timeline_moment_edit))) {
                    actionEdit();
                }
                dialog.dismiss();
            }
        });
        dialog.show();
    }

    private void actionEdit() {

        File bitmapFile = mAdapter.getBitmap();
        if (bitmapFile != null) {
            mCreativeHandler.startFeather(Uri.fromFile(bitmapFile));
        }


        //final MomentPojo momentPojo = mMoments.get(mVp.getCurrentItem());
        //final String picUrl = Utility.getImageBySize(momentPojo.getContent(), MediaUtils.SIZE_MEDIUM, MediaUtils.SIZE_ORIGINAL);
        //Uri picUri = Uri.parse(picUrl);
        //mCreativeHandler.startFeather(picUri);
        //File imageFile = DBManager.getImageFile(TimelineMomentActivity.this, momentPojo.toMomentDB(mStoryDB));=
    }

    private void actionDelete() {
        MomentPojo currentMomentPojo = mMoments.get(mVp.getCurrentItem());
        MomentOptions.actionDeleteMoment(TimelineMomentActivity.this, currentMomentPojo, mMoments.size(), mStory.getID());
        finish();
    }

    private void actionRotate(boolean isClockWise) {
        MomentPojo momentPojo = mMoments.get(mVp.getCurrentItem());

        new ImageRotatePutRequest(momentPojo.getID(), isClockWise, this);

        float currentRotation = Float.parseFloat(mMomentDB.getRotation());
        if (isClockWise) {
            currentRotation += 90;
        } else {
            currentRotation -= 90;
        }

        if (mShouldSaveToDB) {
            mMomentDB.setRotation(currentRotation + "");
            mMomentDB.save();
            momentPojo = mMomentDB.converter();
        }

        momentPojo.setRotation(currentRotation + "");
        mMoments.set(mSelectedIndex, momentPojo);
        setViewPager();

        AppInstance.sharedInstance().getBus().post(new TimelineBusMomentChanged(momentPojo, TimelineBusMomentChanged.KEY_STATE_ROTATE));
    }

    @Override
    public void onImageRotateResult() {
        Utility.d("image rotated ");
    }

    @Override
    public void onErrorResult(String err) {}

}

@Override
protected void onDestroy() {
    AppInstance.sharedInstance().getBus().unregister(this);
    super.onDestroy();
}
….
// MARK: Crop

private void beginCrop(Uri source) {
    Crop.of(source, cropFileUri).asSquare().start(this);
}
…..
}

适配器:

public class TimelineMomentPagerAdapter extends PagerAdapter {
…
public TimelineMomentPagerAdapter(Context mContext, List<MomentPojo> mArray, StoryDB aStoryDB) {
    this.mContext = mContext;
    this.mArray = mArray;
    this.mStoryDB = aStoryDB;
}

public File getBitmap() {
    convertBitmapToFile();
    return mCurrentBitmapFile;
}

public void setBitmap(View aView) {
    ImageView imageView = (ImageView) aView.findViewById(R.id.mIvVpContent);
    if (imageView != null) {
        mCurrentImageViewBitmap = getBitmap(imageView);
    }
}

private void convertBitmapToFile() {
    /*View currentPagerView = mVp.getChildAt(mVp.getCurrentItem());
    ImageView contentView = (ImageView) currentPagerView.findViewById(R.id.mIvVpContent);
    Bitmap bitmap = getBitmap(contentView);*/

    final File bitmapFolder = new File(mContext.getCacheDir(), "bitmap");
    if (!bitmapFolder.exists()) {
        bitmapFolder.mkdir();
    }

    mCurrentBitmapFile = new File(bitmapFolder, "currentBitmap");

    try {
        if (mCurrentBitmapFile.exists()) {
            mCurrentBitmapFile.delete();
        }

        mCurrentBitmapFile.createNewFile();
        FileOutputStream stream = new FileOutputStream(mCurrentBitmapFile);

        if (mCurrentImageViewBitmap != null) {
            mCurrentImageViewBitmap.compress(Bitmap.CompressFormat.JPEG, 75, stream);
        }

        stream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@Override
public int getCount() {
    return mArray.size();
}

@Override
public boolean isViewFromObject(View view, Object object) {
    return view == object;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    container.removeView((RelativeLayout) object);
}

@Override
public Object instantiateItem(ViewGroup container, final int position) {

    final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    final View v = inflater.inflate(R.layout.timeline_moment_viewpager, container, false);
    final MomentPojo momentPojo = mArray.get(position);

    mIvContent = (ImageView) v.findViewById(R.id.mIvVpContent);
    mTvContent = (TextView) v.findViewById(R.id.mTvVpContent);
    mIvPlay = (ImageView) v.findViewById(R.id.mIvPlay);
    mPbProgressBar = (ProgressBar) v.findViewById(R.id.pbProgress);

    final String type = momentPojo.getType();
    final String content = momentPojo.getContent();

    switch (type) {
        case TimelineUtils.KEY_TYPE_IMAGE: //---------------------------------------------------IMAGE
            mIvPlay.setVisibility(View.GONE);
            mIvContent.setVisibility(View.VISIBLE);
            mTvContent.setVisibility(View.GONE);

            final String contentHigherQuality = momentPojo.getContentHigherQuality();
            final String newContent;
            if (JavaUtils.isNotNullNotEmptyNotWhiteSpaceOnly(contentHigherQuality)) {
                newContent = contentHigherQuality;
            } else if (JavaUtils.isNotNullNotEmptyNotWhiteSpaceOnly(content)) {
                newContent = content;
            } else {
                newContent = momentPojo.getLocalPath();
            }

            mPbProgressBar.setVisibility(View.VISIBLE);
            Glide.with(BaseApplication.getInstance()).load(newContent).asBitmap().placeholder(R.drawable.ic_action_picture).into(new SimpleTarget<Bitmap>() {
                @Override
                public void onResourceReady(Bitmap bitmap, GlideAnimation<? super Bitmap> glideAnimation) {
                    if (bitmap != null) {
                        mIvContent.setImageBitmap(bitmap);
                    }
                    mPbProgressBar.setVisibility(View.INVISIBLE);
                }

                @Override
                public void onLoadFailed(final Exception e, final Drawable errorDrawable) {
                    mPbProgressBar.setVisibility(View.INVISIBLE);
                }
            });

            setImageRotation(momentPojo.getRotation());
            if (position == 0 && !mWasCurrentImageBitmapInitialized) {
                mCurrentImageViewBitmap = getBitmap(mIvContent);
                mWasCurrentImageBitmapInitialized = true;
            }
            break;
        case TimelineUtils.KEY_TYPE_TEXT:  //---------------------------------------------------TEXT
        case TimelineUtils.KEY_TYPE_LINK:  //---------------------------------------------------LINK
            ….
            break;
        case TimelineUtils.KEY_TYPE_AUDIO: //---------------------------------------------------AUDIO
        case TimelineUtils.KEY_TYPE_VIDEO: //---------------------------------------------------VIDEO
            …
            break;

        case TimelineUtils.KEY_TYPE_PDF: //-----------------------------------------------------PDF
            ….
            break;

        case TimelineUtils.KEY_TYPE_YOUTUBE: //---------------------------------------------------VIDEO
           ….
            break;

    }

    container.addView(v);
    return v;
}
….

public Bitmap getBitmap(ImageView aImageView) {
    Bitmap image = null;
    if (aImageView == null) return null;
    Drawable drawable = aImageView.getDrawable();
    if (drawable != null) {
        if (drawable instanceof GlideBitmapDrawable) {
            GlideBitmapDrawable bitmapDrawable = (GlideBitmapDrawable) aImageView.getDrawable();
            image = bitmapDrawable.getBitmap();
        } else if (drawable instanceof BitmapDrawable) {

            BitmapDrawable bitmapDrawable = (BitmapDrawable) aImageView.getDrawable();
            image = bitmapDrawable.getBitmap();
        }
    }
    return image;
}
….
}

此代码有效,但并非总是如此,在某些情况下 currentView 在传递此方法后为空。经过一些调试会话后,我发现虽然onPageSelected给了我可以是例如 10 的真实索引,但视图寻呼机始终将其视图保持在 0-2 位置。因此,在刷卡时,所有三个项目都被交换,但它们仍保持在 0-2 的位置。

我怎样才能完成我的任务?

4

1 回答 1

2

首先,去掉OnPageChangeListener修改适配器中某些内容的所有代码。

将位图映射添加到适配器:

private Map<Integer, Bitmap> mBitmapMap;
private Map<Integer, View> mViewMap;

通货膨胀instantiateItem()后:

mViewMap.put(position, v);

在您的回调中onResourceReady()

mBitmap.put(position, bitmap); // position is final

destroyItem()

mBitmapMap.put(position, null);  // remove from map
mViewMap.put(position, null);

然后实现新方法:

public Bitmap getBitmapAt(int position) {
    return mBitmapMap.get(position);
}

public View getViewAt(position) {
    return mViewMap.get(position);
}

来自活动的调用:

bitmap = mAdapter.getBitmapAt(mVp.getCurrentItem());
view = mAdapter.getViewAt(mVp.getCurrentItem());

现在您可以将屏幕外页面限制保留为默认值。

于 2015-12-16T11:05:23.823 回答