【发布时间】:2016-03-09 10:40:13
【问题描述】:
我正在尝试做简单的幻灯片,有我正在使用的代码:
public class Pictures extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
private ImageView picture;
private Integer resourceImage;
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
public void run() {
showNewPicture(true);
handler.postDelayed(this, 1000);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
// initialization here
final Button slideshowStart = (Button) findViewById(R.id.slideshow_start);
// I'm starting slideshow using this:
slideshowStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.removeCallbacks(runnable);
handler.post(runnable);
}
});
final Button slideshowStop = (Button) findViewById(R.id.slideshow_stop);
// I'm stopping slideshow using this:
slideshowStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.removeCallbacks(runnable);
}
});
}
private void showNewPicture(Boolean next){
// defining resource ID for the new picture, i. e.:
resourceImage = R.drawable.some_picture;
setScaledImage(picture, resourceImage);
picture.setTag(newTag);
}
// all the code below is to scale images to the actual size of the view
private void setScaledImage(ImageView imageView, final int resId) {
final ImageView iv = imageView;
ViewTreeObserver viewTreeObserver = iv.getViewTreeObserver();
viewTreeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
iv.getViewTreeObserver().removeOnPreDrawListener(this);
int imageViewHeight = iv.getMeasuredHeight();
int imageViewWidth = iv.getMeasuredWidth();
iv.setImageBitmap(
decodeSampledBitmapFromResource(getResources(),
resId, imageViewWidth, imageViewHeight));
return true;
}
});
}
private static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds = true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
private static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
if(height > width){
while ((halfHeight / inSampleSize) >= reqHeight) {
inSampleSize *= 2;
}
}else{
while ((halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
}
return inSampleSize;
}
}
当我通过单击按钮调用 showNewPicture(true) 时,它可以正常工作并更新 ImageView 的源。但是当我使用提供的代码运行幻灯片时,它只会在我单击“开始”和“停止”按钮时发生变化。 runnable 里面的代码执行,所以如果我有 10 张图片,启动幻灯片,等待大约 5 秒然后点击“停止”,ImageView 将显示第 6 张图片。另外,如果我在可运行文件中替换该行
handler.postDelayed(this, 1000);
与
handler.post(this);
它工作得很好,我的 ImageView 正在更新,但过程是恒定的,我想设置一些延迟,这就是我使用“postDelayed”的原因。 我也尝试过这样声明 Handler:
private Handler handler = new Handler(Looper.getMainLooper());
并得到相同的结果。 此外,当我将带有 Pictures.this 上下文的 Toast 添加到可运行时 - 它会显示出来,所以我也尝试过像这样声明可运行:
private Runnable runnable = new Runnable() {
public void run() {
Pictures.this.showNewPicture(true);
Pictures.this.handler.postDelayed(this, 1000);
}
};
但它会导致相同的结果。 我在这里错过了什么?
【问题讨论】:
-
不,一切正常,日志显示没有错误,只是 ImageView 在我使用“postDelayed”时没有更新。
标签: android imageview runnable android-handler