EDIT: CODE NOW FIXED
I'm trying to create a dynamically populated frame animation for a simple slot reel. I create a random sequence of 50 animated images to make it look like the reel is spinning, then add the final three symbols at the end.
My problem is that each time this method is run, it adds the frames onto the previous Animation. The first time it is run, the animation has 53 frames, the second time it has 106 frames, etc. I want to reset/clear the animation each time it is run, but I cannot figure out how to do so. If anyone has any ideas it would be greatly appreciated!
private void animate(int r1c1, int r2c1, int r3c1, int r1c2, int r2c2, int r3c2, int r1c3, int r2c3, int r3c3) {
ImageView imgView = (ImageView)findViewById(R.id.animationImage);
imgView.setVisibility(ImageView.VISIBLE);
AnimationDrawable frameAnimation = new AnimationDrawable();
BitmapDrawable cherry = (BitmapDrawable)getResources().getDrawable(R.drawable.cherry);
BitmapDrawable grape = (BitmapDrawable)getResources().getDrawable(R.drawable.grape);
BitmapDrawable lemon = (BitmapDrawable)getResources().getDrawable(R.drawable.lemon);
BitmapDrawable lucky7 = (BitmapDrawable)getResources().getDrawable(R.drawable.lucky7);
BitmapDrawable watermelon = (BitmapDrawable)getResources().getDrawable(R.drawable.watermelon);
BitmapDrawable orange = (BitmapDrawable)getResources().getDrawable(R.drawable.orange);
BitmapDrawable[] symbols = {cherry,watermelon,grape,lemon,orange,lucky7};
// frameAnimation = (AnimationDrawable) imgView.getBackground();
for(int i = 0; i < 50; i++) {
frameAnimation.addFrame(symbols[(int)(Math.random() * 6)], 50);
}
frameAnimation.addFrame(symbols[r3c1], 200);
frameAnimation.addFrame(symbols[r2c1], 200);
frameAnimation.addFrame(symbols[r1c1], 200);
imgView.setBackgroundDrawable(frameAnimation);
if (frameAnimation.isRunning()) {
frameAnimation.stop();
frameAnimation.selectDrawable(0);
frameAnimation.start();
}
else {
frameAnimation.start();
}
}
Here is my frameanimation.xml file
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
</animation-list>
To clear the animation from any view you can use view.clearAnimation()
Provide your complete code for more clearification.
You can try this: Reset its drawable resource and restart animation.
if (frameAnimation.isRunning()) {
frameAnimation.stop();
imgView.setBackgroundDrawable(null);
imgView.setBackgroundResource(R.drawable.frame_animation);
frameAnimation.start();
}
Or you can use selectDrawable:
if (frameAnimation.isRunning()) {
frameAnimation.stop();
frameAnimation.selectDrawable(0);
frameAnimation.start();
}
Hope this helps.
Related
I am randomizing the location of a button on a Relative View everytime a button is clicked. I am doing this by changing the margins of the buttons programatically as shown in the code:
Button testbtn = findViewById(R.id.testbtn);
testbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Get Screen size
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
//Save dimensions in variables
int widthScreen = metrics.widthPixels;
int height = metrics.heightPixels;
TextView width_height = findViewById(R.id.width_height);
//Declare random
Random randomDimension = new Random();
//Declare layout params
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
params.rightMargin = 608;
params.leftMargin = 428;
params.topMargin = randomDimension.nextInt(height) +1;
//params.setMargins();
buttonIDs[1].setLayoutParams(params);
width_height.setText(params.leftMargin+" "+params.rightMargin);
}
});
In this case, "buttonIDs[]" is an array i declared earlier in the class and "testbtn" is the button that when pressed, randomizes the position of my button.
However, these specific margins produce the following image
enter image description here
and I need:
enter image description here
Does anyone know why this is happening and how to fix it?
You set:
params.rightMargin = 608;
params.leftMargin = 428;
So the device must be 608+428+width of the button at least wide. Is it?
A short question regarding the ColorFilter() function; I am trying to replace an specific color of an Image with an new color:
Default:
result:
So in this example I just want to replace the red color with the blue color. But don't modify the black color of this image.
At the moment Iam using the following code:
int color = Color.parseColor("#0000FF");
iv1.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
From the description of the "PorterDuff" Mode I should use "SRV_ATOP". But how should I use this mode so that only the red color will be replaced?
I've now found a way which works perfectly. So for everyone who faces the same probleme...here is the code which works for me:
//Decode *.png file to Bitmap
Bitmap Bitmap_temp = BitmapFactory.decodeResource(getResources(), R.drawable.image_1);
Bitmap Bitmap_final = Bitmap_temp.copy(android.graphics.Bitmap.Config.ARGB_8888, true);
//Get Pixel and change color if pixel color match
int [] allpixels = new int [Bitmap_final.getHeight() * Bitmap_final.getWidth()];
Bitmap_final.getPixels(allpixels, 0, Bitmap_final.getWidth(), 0, 0, Bitmap_final.getWidth(), Bitmap_final.getHeight());
for(int i = 0; i < allpixels.length; i++)
{
if(allpixels[i] == Color.parseColor("#fff000"))
{
allpixels[i] = Color.parseColor("#0D0D0D");
}
}
Bitmap_final.setPixels(allpixels,0,Bitmap_final.getWidth(),0, 0, Bitmap_final.getWidth(),Bitmap_final.getHeight());
//Set Bitmap to ImageView
iv_image1.setImageBitmap(Bitmap_final);
I have two image that is
and this:
I need to place that image (stacked) in a single ImageView. I tried to use blend mode, but doesn't work for ImageView like
Group group = new Group();
group.setBlendMode(BlendMode.SRC_OVER);
// tempImage is array of buffered Images
for(int i=0; i < tempImage.length ;i++){
if(tempImage[i] != null){
ImageView view = new ImageView();
Image im = SwingFXUtils.toFXImage(tempImage[i],
null );
view.setImage(im);
group.getChildren().add(view);
}
}
Just a little trick, instead of using BlendModeuse a HBox, add the images inside the HBox and set the HBox inside the Group
Group group = new Group();
HBox box = new HBox
// tempImage is array of buffered Images
for(int i=0; i < tempImage.length ;i++){
if(tempImage[i] != null){
ImageView view = new ImageView();
Image im = SwingFXUtils.toFXImage(tempImage[i],
null );
view.setImage(im);
box.getChildren().add(view);
}
}
group.getChildren.add(box);
But this wont help you to get the new image, guess you don't even need it !
I am making an Android game, but when I load my Bitmaps, I get a memory error. I know that this is caused by a very large Bitmap (it's the game background), but I don't know how I could keep from getting a "Bitmap size extends VM Budget" error. I can't rescale the Bitmap to make it smaller because I can't make the background smaller. Any suggestions?
Oh yeah, and here's the code that causes the error:
space = BitmapFactory.decodeResource(context.getResources(),
R.drawable.background);
space = Bitmap.createScaledBitmap(space,
(int) (space.getWidth() * widthRatio),
(int) (space.getHeight() * heightRatio), false);
You're going to have to sample down the image. You can't "scale" it down smaller than the screen obviously, but for small screens etc it doesn't have to be as high resolution as it is for big screens.
Long story short you have to use the inSampleSize option to downsample. It should actually be pretty easy if the image fits the screen:
final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
final Display display = wm.getDefaultDisplay();
final int dimension = Math.max(display.getHeight(), display.getWidth());
final Options opt = new BitmapFactory.Options();
opt.inJustDecodeBounds = true;
InputStream bitmapStream = /* input stream for bitmap */;
BitmapFactory.decodeStream(bitmapStream, null, opt);
try
{
bitmapStream.close();
}
catch (final IOException e)
{
// ignore
}
final int imageHeight = opt.outHeight;
final int imageWidth = opt.outWidth;
int exactSampleSize = 1;
if (imageHeight > dimension || imageWidth > dimension)
{
if (imageWidth > imageHeight)
{
exactSampleSize = Math.round((float) imageHeight / (float) dimension);
}
else
{
exactSampleSize = Math.round((float) imageWidth / (float) dimension);
}
}
opt.inSampleSize = exactSampleSize; // if you find a nearest power of 2, the sampling will be more efficient... on the other hand math is hard.
opt.inJustDecodeBounds = false;
bitmapStream = /* new input stream for bitmap, make sure not to re-use the stream from above or this won't work */;
final Bitmap img = BitmapFactory.decodeStream(bitmapStream, null, opt);
/* Now go clean up your open streams... : ) */
Hope that helps.
This may help you: http://developer.android.com/training/displaying-bitmaps/index.html
From the Android Developer Website, a tutorial on how to efficiently display bitmaps + other stuff. =]
I don't understand why are you using ImageBitmap? for background. If its necessary , its okay. Otherwise please use Layout and set its background because you are using background image.
This is important. (Check Android docs. They have clearly indicated this issue.)
You can do this in following way
Drawable d = getResources().getDrawable(R.drawable.your_background);
backgroundRelativeLayout.setBackgroundDrawable(d);
In most android devices the Intent size equals 16MB. You MUST Follow these instructions Loading Large Bitmap Efficiently
I am making a icon for my app.. The app is basically a friend finder. I am creating a overlay that looks much like the icons from Google Latitude. I have an image that changes due to the user and I have the boarder. I've been able to do the layered drawable and overlay fine, but the problem is, the image stretches to the size of the border. This is a problem because, if you've never seen the Google Lat icons, it has a point on the bottom with open space between it.
What I need to do is, somehow restrict the size of the changing image to the bounds of the square portion of the border. Any Help would be much appreciated. Here is my snippet:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 25;
Bitmap bit = BitmapFactory.decodeFile(photo, options);
draw = new BitmapDrawable(bit);
Resources r = getResources();
Drawable[] layers = new Drawable[2];
layers[0] = draw;
layers[1] = r.getDrawable(R.drawable.border);
LayerDrawable layerDrawable = new LayerDrawable(layers);
draw = layerDrawable;
}else{
draw = this.getResources().getDrawable(R.drawable.androidmarker);
}
HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(draw, this);
GeoPoint point = new GeoPoint(lat,lon);
OverlayItem overlayitem = new OverlayItem(point, username, avail + " : " + status + " : Position updated at : " + update_at);
items.add(overlayitem);
itemizedoverlay.addOverlay(overlayitem);
mapOverlays.add(itemizedoverlay);
Funny that shorty after I posted this, I found the answer. I was looking in all of the wrong places to resize the image. I tried the bitmap, the drawable, the layers inside of the layerdrawable. But, what I never tried was the layerdrawable itself. The solution is below:
Resources r = getResources();
Drawable[] layers = new Drawable[2];
layers[0] = draw;
layers[1] = r.getDrawable(R.drawable.border);
LayerDrawable layerDrawable = new LayerDrawable(layers);
layerDrawable.setLayerInset(0, 0, 0, 0, 12);
draw = layerDrawable;
The layerDrawable inset method is as follows:
layerDrawable.setLayerInset(*index of layer*, *left inset*, *top*, *right*, *bottom*);
Thanks guys!