- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 View 寻呼机,其中每个页面都是一个自定义 View ( ... 而不是 Fragment
),我正在使用 LayoutInflator
进行扩充。 .每个自定义 View 都有一个 ImageView
在其中填充了来自网络的图像,使用 Glide
图书馆。
我的任务是当用户滚动时每次他更改页面时抛出 View 寻呼机我需要检索 Bitmap
正在填充当前显示的 ImageView
.
我尝试使用集合 OnPageChangeListener
在查看寻呼机上并使用 onPageSelected
使用 viewPager.getChildAt()
获取当前 View 的方法方法或 viewPager.getFocusedChild()
.
代码如下:
Activity :
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 为 null。经过一些调试 session 后,我发现虽然 onPageSelected
给我真实的索引,例如 10, View 寻呼机始终将其 View 保持在 0-2 位置。因此,在滑动时所有三个项目都被交换,但它们仍保持在 0-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);
}
来自 Activity 的调用:
bitmap = mAdapter.getBitmapAt(mVp.getCurrentItem());
view = mAdapter.getViewAt(mVp.getCurrentItem());
现在您可以将离屏页面限制保留为默认值。
关于android - 如何在没有标签的情况下获取当前 View 寻呼机 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34308264/
我是 Java 新手,这是我的代码, if( a.name == b.name && a.displayname == b.displayname && a.linknam
在下面的场景中,我有一个 bool 值。根据结果,我调用完全相同的函数,唯一的区别是参数的数量。 var myBoolean = ... if (myBoolean) { retrieve
我是一名研究 C++ 的 C 开发人员: 我是否正确理解如果我抛出异常然后堆栈将展开直到找到第一个异常处理程序?是否可以在不展开的情况下在任何 throw 上打开调试器(即不离开声明它的范围或任何更高
在修复庞大代码库中的错误时,我观察到一个奇怪的情况,其中引用的动态类型从原始 Derived 类型更改为 Base 类型!我提供了最少的代码来解释问题: struct Base { // some
我正在尝试用 C# 扩展给定的代码,但由于缺乏编程经验,我有点陷入困境。 使用 Visual Studio 社区,我尝试通过控制台读出 CPU 核心温度。该代码使用开关/外壳来查找传感器的特定名称(即
这可能是一个哲学问题。 假设您正在向页面发出 AJAX 请求(这是使用 Prototype): new Ajax.Request('target.asp', { method:"post", pa
我有以下 HTML 代码,我无法在所有浏览器中正常工作: 我试图在移动到
我对 Swift 很陌生。我如何从 addPin 函数中检索注释并能够在我的 addLocation 操作 (buttonPressed) 中使用它。我正在尝试使用压力触摸在 map 上添加图钉,在两
我设置了一个详细 View ,我是否有几个 Nib 文件根据在 Root View Controller 的表中选择的项目来加载。 我发现,对于 Nibs 的类,永远不会调用 viewDidUnloa
我需要动态访问 json 文件并使用以下代码。在本例中,“bpicsel”和“temp”是变量。最终结果类似于“data[0].extit1” var title="data["+bpicsel+"]
我需要使用第三方 WCF 服务。我已经在我的证书存储中配置了所需的证书,但是在调用 WCF 服务时出现以下异常。 向 https://XXXX.com/AHSharedServices/Custome
在几个 SO 答案(1、2)中,建议如果存在冲突则不应触发 INSERT 触发器,ON CONFLICT DO NOTHING 在触发语句中。也许我理解错了,但在我的实验中似乎并非如此。 这是我的 S
如果进行修改,则会给出org.hibernate.NonUniqueObjectException。在我的 BidderBO 类(class)中 @Override @Transactional(pr
我使用 indexOf() 方法来精细地查找数组中的对象。 直到此刻我查了一些资料,发现代码应该无法正常工作。 我在reducer中尝试了上面的代码,它成功了 let tmp = state.find
假设我有以下表格: CREATE TABLE Game ( GameID INT UNSIGNED NOT NULL, GameType TINYINT UNSIGNED NOT NU
代码: Alamofire.request(URL(string: imageUrl)!).downloadProgress(closure: { (progress) in
我是一名优秀的程序员,十分优秀!