Android - How to position View off-screen?

I am trying to animate a simple ImageView in my application, and I want it to slide at the bottom of the screen and come to rest, where the top 50 pixels of the view are outside the top of the screen (for example, the end position of the ImageView should be -50px in X). I tried using AbsoluteLayout for this, but it actually cuts off the top 50 pixels of the ImageView so that the top 50px is never displayed. I need the top 50 pixels of the image to be visible / displayed during the animation, and then just make it rest a bit. I hope I explained it quite well.

Here is what I am currently using as a layout and slide animation (this does not currently display 50px ImageView images):

Markup:

<?xml version="1.0" encoding="utf-8"?> <AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:layout_width="fill_parent" android:id="@+id/QuickPlayClipLayout"> <ImageView android:id="@+id/Clip" android:background="@drawable/clip" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_y="-50dp"> </ImageView> </AbsoluteLayout> 

Animation:

 <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromYDelta="100%p" android:toYDelta="0" android:duration="1000"/> <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="1000" /> </set> 

Thanks in advance.

+52
android layout animation imageview
Mar 31 '10 at 16:54
source share
5 answers

I figured out a solution that should be easy to implement. This includes modifying the layout and activity inflating the layout ... see below:

Activity (QuickPlay.java):

 public class QuickPlay extends Activity implements AnimationListener { private ImageView myImageView; private LinearLayout LL; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.quick_play_screen); myImageView = (ImageView) this.findViewById(R.id.Clip); LL = (LinearLayout) this.findViewById(R.id.QuickPlayClipLayout); //finally Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide_in_quickplay); anim.setAnimationListener(this); LL.startAnimation(anim); } @Override public void onAnimationEnd(Animation animation){} @Override public void onAnimationRepeat(Animation animation){} @Override public void onAnimationStart(Animation animation) { // This is the key... //set the coordinates for the bounds (left, top, right, bottom) based on the offset value (50px) in a resource XML LL.layout(0, -(int)this.getResources().getDimension(R.dimen.quickplay_offset), LL.getWidth(), LL.getHeight() + (int)this.getResources().getDimension(R.dimen.quickplay_offset)); } } 

New LinearLayout (CustomLinearLayout.java):

 public class CustomLinearLayout extends LinearLayout { private Context myContext; public CustomLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); myContext = context; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec+((int)myContext.getResources().getDimension(R.dimen.quickplay_offset))); } } 

Layout (/res/layout/quick_play_screen.xml):

 <?xml version="1.0" encoding="utf-8"?> <com.games.mygame.CustomLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:layout_width="fill_parent" android:id="@+id/QuickPlayClipLayout"> <ImageView android:id="@+id/Clip" android:background="@drawable/clip" android:layout_width="fill_parent" android:layout_height="wrap_content"> </ImageView> </com.games.mygame.CustomLinearLayout> 

Resource (/res/values/constants.xml):

 <?xml version="1.0" encoding="utf-8"?> <resources> <dimen name="quickplay_offset">50dp</dimen> </resources> 

Animation (/res/anim/slide_in_quickplay.xml):

 <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromYDelta="100%p" android:toYDelta="0" android:duration="1000"/> <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="1000" /> </set> 

Now the program does what I need. The entire layout starts from the screen below, slides in 1 second and comes to its senses, where the top of the layout is actually 50 pixels on top of the screen (i.e. LL.getTop() = -50 ), and the bottom of the layout is on the bottom screen (i.e. LL.getBottom() = 530 = 480 + 50 ).

+31
Apr 02 '10 at 2:38
source share

To place my view off the screen, I used the following code:

 View myView = /* view you want to position offscreen */ int amountOffscreen = (int)(myView.getWidth() * 0.8); /* or whatever */ boolean offscreen = /* true or false */ int xOffset = (offscreen) ? amountOffscreen : 0; RelativeLayout.LayoutParams rlParams = (RelativeLayout.LayoutParams)myView.getLayoutParams(); rlParams.setMargins(-1*xOffset, 0, xOffset, 0); myView.setLayoutParams(rlParams); 

This code will place myView off-screen by Offscreen, which in this case puts 80% of the screen onto the screen, leaving only 20% on the screen.

Do not use the layout () method directly - Android will make subsequent calls to invalidate your view for random reasons, and only layoutParams are saved for invalid calls. If you're interested, look at lines 904 through 912 of this file to find out why you need to change layoutParams.

+29
Apr 19 2018-12-12T00
source share

Instead, we can simply give negative layout_margin values ​​(Top / left / right / bottom) for example: If you want your view to be disconnected from the top of the screen, you can specify

 android:layout_marginTop="-40dp" 
+21
May 13 '15 at 9:29
source share

This is easy to do if you move on to using Canvas ; those supports that capture the screen without any problems. However, it will be more difficult to implement. You will need to implement a custom View and write your own animation in the code. In essence, this boils down to simple 2D graphics processing, and not to representations using embedded XML animations. There may be a way to do this using XML, but I'm more familiar with canvases. A very good place to see how this is handled in code is the Lunar Lander game example that comes with the SDK.

Approximately following steps:

  • Place the custom view in an XML file using something like <your.package.AnimatingView> , setting its size to fill-parent.

  • Then define an AnimatingView class that extends SurfaceView and implements SurfaceHolder.Callback . (This gives you access to the Canvas drawing immediately, rather than using the invalidate() method. This is important because invalidate () is updated only when the stream is inactive, for example, at the end of the loop. To implement your animation, you need to immediately draw.)

  • Then you can implement a loop that draws a moving image across the screen. The cycle should begin by drawing the entire background (because the canvas does not automatically erase), and then draws the image in a new position depending on the elapsed time. For example, if you want your animation to take 1 second, then you know that if 200 ms has passed, the view should only move 200/1000 or 1/5 of the way from the starting position to the ending position.

You can see some examples of what I mean in my other answers to animation questions: the main answer about the usefulness of using SurfaceView and an example of a loop to use . Note: the second question was about turning, and therefore, some of the difficulties that I spoke of will not be relevant to you. Good luck

+9
Apr 01 '10 at 13:40
source share

I had a viewing group with children and dragged the view onto the screen below - sort of like a drawer. I would then let go, and if the upper border of the upper group of views was in the upper half of the screen, I would animate it from above after the user released the touch.

When this happens, images in viewgroup child groups will be cropped during the animation, but then shown after the animation.

Problem: The height of the view group was wrap_content. I solved this by setting the height to a value that stretched from the screen to the start of the animation.

+2
Jan 23 '14 at 20:07
source share



All Articles