图库活动:
==================
TextView (tv)
------------------
| tv | tv | tv |
------------------
GalleryFragment: dynamically created; replaces FrameLayout
FrameLayout: W&H: match_parent
imageView: W&H are match_parent; scaleType: fitCenter;
layout_below: the tv's above;
layout_above: the TextView below;
result: imageView fits snuggly between.
Parent: RelativeLayout W&H: match_parent
------------------
TextView
==================
图库活动描述:此活动一次显示一个属于特定集合的图像。用户点击图片:新片段显示下一张图片。
我一直有几天的问题,想弄清楚如何:
onPreDraw()
然后我的代码关闭了比赛。 ......但我不知道如何解决它。synchronization
可能是答案,但我以前从未使用它,我认为我没有正确使用它。if(workerThread == null)
检查可能会有效......但它只是放慢了一小段时间。此时我迷路了。我不知道如何获取隐藏在动态添加的片段内的ImageView的尺寸,而使用这些尺寸来缩小位图大小,然后调整大小将位图加载到片段的ImageView中。
如果您需要任何澄清,请询问。
下面是GalleryFragment的onCreateView和BitmapWorkerTask的代码。然后在下面是我过滤的logcat的粘贴。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// inflate view
View view = inflater.inflate(R.layout.frag_gallery_image, container, false);
// get view handles
imageView = (ImageView)view.findViewById(R.id.gallery_image);
// TESTING
ViewTreeObserver vto = imageView.getViewTreeObserver();
vto.addOnPreDrawListener(new OnPreDrawListener() {
@Override
public boolean onPreDraw() {
// TESTING
viewWidth = imageView.getMeasuredWidth();
viewHeight = imageView.getMeasuredHeight();
Log.d(TAG, SCOPE +"onPreDraw viewWidth: " +viewWidth +", viewHeight: " +viewHeight);
// TESTING: Added because "synchronization" attempt didn't work
if(bmwt == null){
loadImage(viewWidth, viewHeight);
}
return true;
}
});
// set view actions
imageView.setOnClickListener(GalleryFragment.this);
return view;
}
/**
* A synchronized method for loading bitmaps in background thread.
* Synchronization: http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
* ...something isn't working as intended...
*/
private synchronized void loadImage(int viewWidth, int viewHeight){
// TESTING
Log.d(TAG, SCOPE +"loadImage viewWidth: " +viewWidth +", viewHeight: " +viewHeight);
bmwt = new BitmapWorkerTask(imageView, viewWidth, viewHeight);
bmwt.execute(imageUri);
}
/**
* BitmapWorkerTask is a subclass of Asynctask for the purpose of loading
* images off of the UI thread.
*/
private class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap>{
private String uri;
private int imageViewWidth;
private int imageViewHeight;
// Constructor.
public BitmapWorkerTask(ImageView imageView, int width, int height){
imageViewWidth = width;
imageViewHeight = height;
}
// Decode image in background.
@Override
protected Bitmap doInBackground(String... params) {
uri = params[0];
final Bitmap bitmap = ImageUtils.decodeSampledBitmapFromUri(uri, imageViewWidth, imageViewHeight);
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null; // use some default bitmap
}
if (bitmap != null) {
Log.d(TAG, SCOPE +"bitmap kilobyte count: "+ bitmap.getByteCount() / 1024);
imageView.setImageBitmap(bitmap);
// make BitmapWorkerTask reference null again.
bmwt = null;
}// else do nothing.
}
}
logcat的。注意在asyncTask的onPostExecute中调用“bitmap kilobyte count”。 ......而且我希望伐木能够停止。
06-13 01:50:41.442: D/ROSS(12982): GalleryFragment: imageUri: /mnt/sdcard/So so so beautiful.jpg
06-13 01:50:41.522: D/ROSS(12982): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 01:50:41.522: D/ROSS(12982): GalleryFragment: loadImage viewWidth: 480, viewHeight: 692
06-13 01:50:41.632: D/ROSS(12982): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 01:50:41.827: D/ROSS(12982): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 01:50:43.053: D/ROSS(12982): GalleryFragment: bitmap kilobyte count: 1183
06-13 01:50:43.142: D/ROSS(12982): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 01:50:43.142: D/ROSS(12982): GalleryFragment: loadImage viewWidth: 480, viewHeight: 692
06-13 01:50:43.632: D/ROSS(12982): GalleryFragment: bitmap kilobyte count: 1183
06-13 01:50:43.713: D/ROSS(12982): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 01:50:43.713: D/ROSS(12982): GalleryFragment: loadImage viewWidth: 480, viewHeight: 692
06-13 01:50:44.023: D/ROSS(12982): GalleryFragment: bitmap kilobyte count: 1183
06-13 01:50:44.101: D/ROSS(12982): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 01:50:44.101: D/ROSS(12982): GalleryFragment: loadImage viewWidth: 480, viewHeight: 692
06-13 01:50:44.332: D/ROSS(12982): GalleryFragment: bitmap kilobyte count: 1183
06-13 01:50:44.414: D/ROSS(12982): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 01:50:44.414: D/ROSS(12982): GalleryFragment: loadImage viewWidth: 480, viewHeight: 692
06-13 01:50:44.681: D/ROSS(12982): GalleryFragment: bitmap kilobyte count: 1183
06-13 01:50:44.761: D/ROSS(12982): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 01:50:44.761: D/ROSS(12982): GalleryFragment: loadImage viewWidth: 480, viewHeight: 692
06-13 01:50:45.151: D/ROSS(12982): GalleryFragment: bitmap kilobyte count: 1183
06-13 01:50:45.227: D/ROSS(12982): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 01:50:45.231: D/ROSS(12982): GalleryFragment: loadImage viewWidth: 480, viewHeight: 692
06-13 01:50:45.521: D/ROSS(12982): GalleryFragment: bitmap kilobyte count: 1183
06-13 01:50:45.593: D/ROSS(12982): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 01:50:45.593: D/ROSS(12982): GalleryFragment: loadImage viewWidth: 480, viewHeight: 692
06-13 01:50:45.962: D/ROSS(12982): GalleryFragment: bitmap kilobyte count: 1183
在实施尼古拉斯的建议后,这里总体上是logcat:
06-13 14:51:44.976: D/ROSS(15465): GalleryFragment: imageUri: /mnt/sdcard/RossAndClay - Copy (12).JPG
06-13 14:51:45.146: D/ROSS(15465): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 14:51:45.146: D/ROSS(15465): GalleryFragment: loadImage viewWidth: 480, viewHeight: 692
06-13 14:51:45.376: D/ROSS(15465): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 14:51:45.422: D/ROSS(15465): GalleryFragment: loadImage viewWidth: 480, viewHeight: 692
06-13 14:51:45.626: D/ROSS(15465): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 14:51:45.626: D/ROSS(15465): GalleryFragment: loadImage viewWidth: 480, viewHeight: 692
06-13 14:51:49.336: D/ROSS(15465): GalleryFragment: bitmap kilobyte count: 1183
06-13 14:51:49.356: D/ROSS(15465): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 14:51:51.327: D/ROSS(15465): GalleryFragment: bitmap kilobyte count: 1183
06-13 14:51:51.336: D/ROSS(15465): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 14:51:53.395: D/ROSS(15465): GalleryFragment: bitmap kilobyte count: 1183
06-13 14:51:53.469: D/ROSS(15465): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 14:54:41.315: D/ROSS(15465): GalleryFragment: imageUri: /mnt/sdcard/RossAndClay - Copy (11).JPG
06-13 14:54:41.402: D/ROSS(15465): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 14:54:41.406: D/ROSS(15465): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 14:54:41.406: D/ROSS(15465): GalleryFragment: loadImage viewWidth: 480, viewHeight: 692
06-13 14:54:41.655: D/ROSS(15465): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 14:54:41.665: D/ROSS(15465): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 14:54:41.665: D/ROSS(15465): GalleryFragment: loadImage viewWidth: 480, viewHeight: 692
06-13 14:54:44.285: D/ROSS(15465): GalleryFragment: bitmap kilobyte count: 1183
06-13 14:54:44.305: D/ROSS(15465): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 14:54:44.305: D/ROSS(15465): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 14:54:46.965: D/ROSS(15465): GalleryFragment: bitmap kilobyte count: 1183
06-13 14:54:47.036: D/ROSS(15465): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
06-13 14:54:47.036: D/ROSS(15465): GalleryFragment: onPreDraw viewWidth: 480, viewHeight: 692
每次单击图像时,logcat中的条目数都会越来越长。我的片段交易看起来像:
/*
* Create the fragment that holds the collection image.
* @param imageUri
*/
private void createImageFragment(String imageUri) {
// With each click wipe previous entry, ie: there's no going back.
getFragmentManager().popBackStack();
// create new fragment
GalleryFragment galleryFrag = GalleryFragment.newInstance(imageUri);
// programmatically add new fragment
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.gallery_imageFrame, galleryFrag, GALLERY_FRAG);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.commit();
}
我写这篇文章的那一刻,我尝试将popBackStack()
更改为popBackStackImmediate()
,这阻止了日益增长的logcat条目列表。现在,在完成了一些测试加载后图像大小,看起来有点大,图像决定了loadImage()的调用次数,这是有意义的(虽然我想阻止它发生)因为(例如)在imageView之前发射了三个asyntasks图像实际上是设置的。所以现在的任务是弄清楚如何确保只调用loadImage()
一次。
有时候一个特定的问题可能会冻结我们的大脑。仅使用类字段private boolean thisMethodCalled = false;
和onPreDraw:
if(!thisMethodCalled){
loadImage(viewWidth, viewHeight);
thisMethodCalled = true;
}
...虽然这并不会因为每次更换片段而不能再次调用PreDraw,但不确定我是否可以做任何事情。
根据this answer中的一条评论收集的概念,只需删除靠近末尾的监听器imageView.getViewTreeObserver().removeOnPreDrawListener(this);
,没有监听器,多次调用方法;显然没有额外的onPreDraw()调用。最后,完全像我预期的那样工作。
ViewTreeObserver vto = imageView.getViewTreeObserver();
vto.addOnPreDrawListener(new OnPreDrawListener() {
@Override
public boolean onPreDraw() {
// TESTING
viewWidth = imageView.getMeasuredWidth();
viewHeight = imageView.getMeasuredHeight();
loadImage(viewWidth, viewHeight);
imageView.getViewTreeObserver().removeOnPreDrawListener(this);
return true;
}
});
答案 0 :(得分:1)
也许尝试将图像视图标记设置为false或true。真正意味着它已经在绘制。它可能会起作用,但不确定它如何处理您的应用程序。
然后你可以拥有像
这样的东西imageView = (ImageView)view.findViewById(R.id.gallery_image);
// we have not loaded the image yet
imageView.setTag(false);
然后在你的预制
上boolean hasLoaded = ((Boolean) imageView.getTag());
// if we have not loaded the image yet
// we want to load it
if(!hasLoaded){
loadImage(viewWidth, viewHeight);
}
然后在后执行
if (bitmap != null) {
Log.d(TAG, SCOPE +"bitmap kilobyte count: "+ bitmap.getByteCount() / 1024);
// we succesfully loaded bitmap
imageView.setTag(true);
imageView.setImageBitmap(bitmap);
// make BitmapWorkerTask reference null again.
bmwt = null;
}
编辑:修改了一些代码以便于阅读