is there a way to display an ImageView progressively from top to down,
like this:
Sorry for the crappy animation.
I'm not very familiar with android animations, but one(a little hackish) way is to wrap the image in a ClipDrawable and animate its level value. For example:
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/clip_source" />
Where clip_source is a drawable:
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:clipOrientation="vertical"
android:drawable="#drawable/your_own_drawable"
android:gravity="bottom" />
Then in code you would have:
// a field in your class
private int mLevel = 0;
ImageView img = (ImageView) findViewById(R.id.imageView1);
mImageDrawable = (ClipDrawable) img.getDrawable();
mImageDrawable.setLevel(0);
mHandler.post(animateImage);
The animateImage is a Runnable object:
private Runnable animateImage = new Runnable() {
#Override
public void run() {
doTheAnimation();
}
};
and the doTheAnimation method:
private void doTheAnimation() {
mLevel += 1000;
mImageDrawable.setLevel(mLevel);
if (mLevel <= 10000) {
mHandler.postDelayed(animateImage, 50);
} else {
mHandler.removeCallbacks(animateImage);
}
}
Related
I have a magic problem. All instance of LayerDrawable change together.
I have several typical Views. So to done my task i decide "I will be used "Composite view". I got a problem:
When i change visibility on one Layer drawable< the change on all.
public abstract class BaseContentExpanded<DATA> extends FrameLayout implements ExpandableLayout.AdditionalAnimators {
// same not imprtand code
#Override
public List<? extends Animator> getAnimators(final boolean togle) {
final Drawable showDrawable;
final Drawable hideDraawable;
final LayerDrawable layerDrawable = (LayerDrawable) vStateSelectionIcon.getDrawable();
if (togle) {
showDrawable = layerDrawable.getDrawable(0);
hideDraawable = layerDrawable.getDrawable(isCanExpand ? 1 : 2);
} else {
hideDraawable = layerDrawable.getDrawable(0);
showDrawable = layerDrawable.getDrawable(isCanExpand ? 1 : 2);
}
ValueAnimator expandAnimator = ValueAnimator.ofFloat(0f, 1f);
expandAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
Log.d(TAG, "getAnimators: " + layerDrawable);
float currentExpandAnimationValue = (float) animation.getAnimatedValue();
showDrawable.setAlpha((int) (255 * currentExpandAnimationValue));
hideDraawable.setAlpha((int) (255 * (1 - currentExpandAnimationValue)));
}
});
return Arrays.asList(expandAnimator);
}
}
And xml for LayerDrawable
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:src="#drawable/ic_close_light"/>
</item>
<item
android:drawable="#drawable/vector_ic_arrow_down_blue_stroke_24dp"/>
<item
android:drawable="#drawable/vector_ic_arrow_right_blue_24dp"/>
</layer-list>
Layout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#drawable/line_divider"
android:orientation="vertical"
android:showDividers="middle"
>
<com.learnx.android.ui.view.filters.LocationFilter
android:id="#+id/location"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<com.learnx.android.ui.view.filters.RatingFilter
android:id="#+id/rating"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
I will be grateful for any help.
I wound the mistake. i forget call mutate();
final LayerDrawable layerDrawable = (LayerDrawable) vStateSelectionIcon.getDrawable();
LayerDrawable copyDrawable = (LayerDrawable) layerDrawable.mutate();
i did the smooth background colour repeating for TextView like below
final Handler mHandler2 = new Handler();
final Runnable mUpdateResults2 = new Runnable() {
public void run() {
ObjectAnimator colorFade = ObjectAnimator.ofObject(tvGoLive, "backgroundColor", new ArgbEvaluator(), Color.parseColor("#FFFFFF"), Color.parseColor("#000000"));
colorFade.setDuration(1000);
colorFade.start();
}
};
final Runnable mUpdateResults3 = new Runnable() {
public void run() {
ObjectAnimator colorFade = ObjectAnimator.ofObject(tvGoLive, "backgroundColor", new ArgbEvaluator(), Color.parseColor("#000000"), Color.parseColor("#FFFFFF"));
colorFade.setDuration(1000);
colorFade.start();
}
};
int delay2 = 1000;
int period2 = 1000;
Timer timer2 = new Timer();
timer2.scheduleAtFixedRate(new TimerTask() {
int rotation = 1;
public void run() {
if(rotation == 1){
mHandler2.post(mUpdateResults2);
rotation = 2;
}else if (rotation == 2) {
mHandler2.post(mUpdateResults3);
rotation = 1;
}
}
}, delay2, period2);
Now i need to set the boarder for this TextView programmatically. For this requirement i tried some codes in SO and Google, but i didn't get the boarder for text view. So, any one give me the code for setting boarder with smooth background colour repeating
Finally i got the solution
1. Drawable xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle" >
<solid android:color="#0000FF" />
</shape>
</item>
</layer-list>
If you need boarder, then add <corners android:radius="5dp" /> inside shape of drawable xml
2. Layout
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dp"
android:background="#drawable/btn_radious" >
<TextView
android:id="#+id/club_detail_go_live_tv"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_centerInParent="true"
android:background="#FFFFFF"
android:drawableLeft="#drawable/icon_go_live_small"
android:ellipsize="end"
android:gravity="center"
android:maxLength="30"
android:padding="5dp"
android:text="#string/app_name"
android:textColor="#000000" />
</RelativeLayout>
3. Code
Code as above question
android ImageView is not bringing to front in RelativeLayout
Tried to call bringtofront() didn't work
tried setting visibility to true didn't work
XML CODE
<?xml version="1.0" encoding="utf-8"?>
<!-- This file is /res/layout/main.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/spellingLevel1Layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<RelativeLayout
android:id="#+id/canvas_container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/magnetboard" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="480dp"
android:layout_marginTop="600dp"
android:adjustViewBounds="true" />
</RelativeLayout>
</LinearLayout>
Java Code
public class spellingLevel1 extends Activity {
rel1 = (RelativeLayout) findViewById(R.id.canvas_container);
mImageView1 = (ImageView) findViewById(R.id.imageView1);
image1();
}
public void randomNumber() {
Random rando = new Random();
currentLetter = myImageList[rando.nextInt(myImageList.length)];
}
public void image1(){
//randomNumber();
mImageView1 = (ImageView) findViewById(R.id.imageView1);
mImageView1.setBackgroundResource(R.drawable.spelling_);
mImageView1.bringToFront();
mImageView1.requestLayout();
}
UPDATED CODE
rel1 = (RelativeLayout) findViewById(R.id.canvas_container);
mImageView1 = (ImageView) findViewById(R.id.imageView1);
image1();
}
public void randomNumber() {
Random rando = new Random();
currentLetter = myImageList[rando.nextInt(myImageList.length)];
}
public void image1(){
//randomNumber();
mImageView1 = (ImageView) findViewById(R.id.imageView1);
mImageView1.setImageResource(R.drawable.spelling_); //updated here to setImageResource
mImageView1.bringToFront();
Still does not show
its not the full code but it should be everything to help you see what is included in here
You should define the image source of the ImageView.
because it's size is set to wrap_content and it has no content, the size stays 0.
I have developed an app which has Frame by Frame animation. I am getting resources from drawable folder. So the size of my apk is huge. Now I would like to get resources from server, but I am unable to come up with an idea to do this.
i have put my code over here
main.xml ::
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ImageView android:id="#+id/simple_anim"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_centerHorizontal="true"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, XMLAnimation"
/>
<Button android:text="Button"
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></Button>
</LinearLayout>
frame_animation_girl.xml ::
<animation-list xmlns:android=
"http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="#drawable/girl0001" android:duration="20" />
<item android:drawable="#drawable/girl0002" android:duration="20" />
<item android:drawable="#drawable/girl0003" android:duration="20" />
<item android:drawable="#drawable/girl0004" android:duration="20" />
<item android:drawable="#drawable/girl0005" android:duration="20" />
<item android:drawable="#drawable/girl0006" android:duration="20" />
</animation-list>
Java file ::
ImageView img = (ImageView) findViewById(R.id.simple_anim);
img.setBackgroundResource(R.drawable.frame_animation_girl);
MyAnimationRoutine mar = new MyAnimationRoutine();
MyAnimationRoutine2 mar2 = new MyAnimationRoutine2();
Timer t = new Timer(false);
t.schedule(mar, 100);
Timer t2 = new Timer(false);
t2.schedule(mar2, 5000);
Buttona = (Button) findViewById(R.id.button1);
final Intent animationIntent = new Intent(this, TranningIntent.class);
Buttona.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startActivity(animationIntent);
finish();
}
});
}
class MyAnimationRoutine extends TimerTask {
MyAnimationRoutine() {
}
public void run() {
ImageView img = (ImageView) findViewById(R.id.simple_anim);
// Get the background, which has been compiled to an
// AnimationDrawable object.
AnimationDrawable frameAnimation = (AnimationDrawable) img
.getBackground();
// Start the animation (looped playback by default).
frameAnimation.start();
}
}
class MyAnimationRoutine2 extends TimerTask {
MyAnimationRoutine2() {
}
public void run() {
ImageView img = (ImageView) findViewById(R.id.simple_anim);
// Get the background, which has been compiled to an
// AnimationDrawable object.
AnimationDrawable frameAnimation = (AnimationDrawable) img
.getBackground();
// stop the animation (looped playback by default).
/* frameAnimation.stop(); */
}
}
}
I think this really depends on what you're trying to do, and what your animations are. Some simpler animations (e.g. rotations) you could get away with animating a single drawable, potentially allowing you to store fewer assets. If you are dealing with really complex animations and potentially many assets, you could always return data from your server that can be interpreted by your client logic into animations programmatically (not via xml).
There is also some discussion of using XML files at runtime in this thread:
Download and replace Android resource files
i have solve this by ::
ImageView img = (ImageView) findViewById(R.id.simple_anim);
animation = new AnimationDrawable();
try {
for(int i=0;i<54;i++)
{
xyz("girl000",i);
}
animation.setOneShot(false);
} catch (Exception e) {
}
img.setBackgroundDrawable(animation);
img.post(new Starter());
}
public void xyz(String str,int x)
{
try {
Bitmap bitmap = BitmapFactory.decodeStream((InputStream) new URL(
"http://sdfsdffff/MRESC/images/test/girl/"+"girl000"+x+".png")
.getContent());
Drawable frame =new BitmapDrawable(bitmap);
animation.addFrame(frame, 50);
} catch (Exception e) {
}
}
class Starter implements Runnable {
public void run() {
animation.start();
}
}
I've a series of still images and total of more than 500 images presented in drawable directory. I need to make an animation (load about 20 images per second). I want it to run smoothly and with no Out Of Memory Exception.
I've idea to do this that images for 2 to 3 seconds (40 to 60 images) should load in memory and displayed and then they should disposed off (release the memory) and then images for next 2 to 3 seconds should load. This technique can prevent Out Of Memory Exception. Its just an idea, I dont know whether its a good idea or not. Please guide me some better idea with some code to go with... If my idea is much better and can work then please tell me some helping code to do that.
After reading replies and doing as you suggest, I've written some code like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/llMain">
<ViewFlipper android:id="#+id/imageflipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView android:id="#+id/ImageView01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerInside"
android:layout_gravity="center" />
</ViewFlipper>
</LinearLayout>
and here is my code for doing animation:
public class Animation extends Activity {
ViewFlipper flipper;
int myIndex = 216;
private final Handler handler = new Handler();
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
flipper=(ViewFlipper)findViewById(R.id.imageflipper);
doTheAutoRefresh();
//displayData();
}
private void doTheAutoRefresh() {
handler.postDelayed(new Runnable() {
public void run(){
displayData(); // this is where you put your refresh code
doTheAutoRefresh();
}
}, 30);
}
private void displayData()
{
Resources r = getResources();
if(myIndex > 230){
myIndex = 216;
ImageView myImg = (ImageView)findViewById(R.id.ImageView01);
myImg.setImageResource(r.getIdentifier("drum0" + myIndex, "drawable", "com.vt.animation"));
myIndex += 1;
flipper.showNext();
}
else{
ImageView myImg = (ImageView)findViewById(R.id.ImageView01);
myImg.setImageResource(r.getIdentifier("drum0" + myIndex, "drawable", "com.vt.animation"));
myIndex += 1;
flipper.showNext();
}
}
}
but its very slow. I've set up the refresh time to 30 milliseconds but actually its not refreshing too fast rather its refresh time is about 1 second. Any suggestion to make it fast to feel like real animation?
Thanks,
Use a FrameAnimation, eg in res/drawable/movie.xml:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item android:drawable="#drawable/frame1" android:duration="50" />
<item android:drawable="#drawable/frame2" android:duration="50" />
<item android:drawable="#drawable/frame3" android:duration="50" />
etc...
</animation-list>
And then in Java:
imageView.setBackgroundResource(R.drawable.movie);
AnimationDrawable anim = (AnimationDrawable) imageView.getBackground();
anim.start();
OK. The biggest problem and the easiest solution I got to go with after so many days. I would never expect that it would be so easy to do... :D
I've used both handler and timer to achieve with just an image view, no flipper, no animator nothing else at all... Here is my solution:
----- main.xml file -----
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/background">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView1">
</ImageView>
And here is the way I have done it:
public class MainActivity extends Activity {
private ImageView _imagView;
private Timer _timer;
private int _index;
private MyHandler handler;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
handler= new MyHandler();
_imagView=(ImageView) findViewById(R.id.imageView1);
_index=0;
_timer= new Timer();
_timer.schedule(new TickClass(), 500, 200);
}
private class TickClass extends TimerTask
{
#Override
public void run() {
// TODO Auto-generated method stub
handler.sendEmptyMessage(_index);
_index++;
}
}
private class MyHandler extends Handler
{
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
try {
Bitmap bmp= BitmapFactory.decodeStream(MainActivity.this.getAssets().open("drum_"+_index+".png"));
_imagView.setImageBitmap(bmp);
Log.v("Loaing Image: ",_index+"");
} catch (IOException e) {
// TODO Auto-generated catch block
Log.v("Exception in Handler ",e.getMessage());
}
}
}
}
Note: I've placed all my images to asset directory.
Its so simple as it can, nothing big to do...
I hope it'll be helpful for someone looking to go like this :)
Loading several images is very expensive.
I think it's better to load a single image containing all the movements of that certain animation. An animation strip.
private Bitmap animation = BitmapFactory.decodeResource(getResources(), R.drawable.myPng);
The idea is to traverse the bitmap.
Well, I'm using viewFlipper, switching between views. Good thing about this one is that u can see previous picture sliding out while the new one slides in.
Inside image displaying method:
if (direction == NEXT) {
viewFlipper.setInAnimation(slideLeftIn);
viewFlipper.setOutAnimation(slideLeftOut);
if (currImg < max)
currImg++;
if (currImg == max)
currImg = 0;
if (currentView == 0) {
currentView = 1;
ImageView iv = (ImageView) findViewById(R.id.ImageView02);
iv.setImageResource(images[currImg]);
} else if (currentView == 1) {
currentView = 2;
ImageView iv = (ImageView) findViewById(R.id.ImageView03);
iv.setImageResource(images[currImg]);
} else {
currentView = 0;
ImageView iv = (ImageView) findViewById(R.id.ImageView01);
iv.setImageResource(images[currImg]);
}
viewFlipper.showNext();
}
else if (direction == PREV) {
viewFlipper.setInAnimation(slideRightIn);
viewFlipper.setOutAnimation(slideRightOut);
if (currImg > 0)
currImg--;
else if (currImg <= 0)
currImg = (max-1);
if (currentView == 0) {
currentView = 2;
ImageView iv = (ImageView) findViewById(R.id.ImageView03);
iv.setImageResource(images[currImg]);
} else if (currentView == 2) {
currentView = 1;
ImageView iv = (ImageView) findViewById(R.id.ImageView02);
iv.setImageResource(images[currImg]);
} else {
currentView = 0;
ImageView iv = (ImageView) findViewById(R.id.ImageView01);
iv.setImageResource(images[currImg]);
}
viewFlipper.showPrevious();
And inside XML file:
<ViewFlipper android:id="#+id/imageflipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView android:id="#+id/ImageView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:layout_gravity="center" />
<ImageView android:id="#+id/ImageView02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:layout_gravity="center" />
<ImageView android:id="#+id/ImageView03"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:layout_gravity="center" />
</ViewFlipper>