program tip

Android — View를 화면 밖으로 배치하는 방법은 무엇입니까?

radiobox 2020. 12. 1. 07:52
반응형

Android — View를 화면 밖으로 배치하는 방법은 무엇입니까?


내 응용 프로그램에서 간단한 ImageView에 애니메이션을 적용하려고하는데 화면 하단에서 슬라이드하여보기의 상단 50px가 화면 상단에서 벗어난 위치 (예 : 최종 위치)로 이동하고 싶습니다. ImageView의 X는 -50px이어야합니다). 이 작업을 수행하기 위해 AbsoluteLayout을 사용하려고 시도했지만 실제로 ImageView의 상위 50px를 잘라내어 상위 50px가 렌더링되지 않습니다. 애니메이션하는 동안 ImageView의 상위 50px를 표시 / 렌더링 한 다음 화면에서 약간 벗어나게해야합니다. 충분히 설명했으면합니다.

다음은 현재 레이아웃 및 슬라이드 인 애니메이션으로 사용중인 것입니다 (현재 ImageView의 상위 50px는 렌더링하지 않음).

형세:

<?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>

생기:

<?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>

미리 감사드립니다.


구현하기 쉬운 해결책을 찾았습니다. 레이아웃을 수정하고 레이아웃을 확장하는 활동을 포함합니다 ... 아래를 참조하세요.

활동 (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));
    }
}

새로운 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)));
    }
}

레이아웃 (/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>

리소스 (/res/values/constants.xml) :

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

애니메이션 (/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>

이 프로그램은 이제 필요한 작업을 정확히 수행합니다. 전체 레이아웃은 하단에서 화면에서 시작하여 1 초 내에 슬라이드되어 레이아웃의 상단이 실제로 화면 상단에서 50px 떨어져 있고 (예 :) LL.getTop() = -50레이아웃의 하단이 하단에 놓이게됩니다. 화면 (예 :) LL.getBottom() = 530 = 480 + 50.


대신 layout_margin (Top / left / right / bottom)에 음수 값을 줄 수 있습니다. 예 : 화면 상단에서보기를 해제하려면 다음을 지정할 수 있습니다.

android:layout_marginTop="-40dp"

To position my view offscreen 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 position myView offscreen by amountOffscreen, which in this case puts 80% of the view offscreen leaving only 20% onscreen.

Do not use the layout() method directly - Android will make subsequent calls to invalidate your view for random reasons and only layoutParams are persisted across invalidate calls. If you are curious, check out lines 904 to 912 of this file to see why you have to modify the layoutParams.


This is easy to do if you make to leap to using a Canvas; those support drawing off the screen without any trouble. However, it will be a more complicated to implement. You'd need to implement a custom View and write your own animation in code. Essentially this comes down to simple 2D graphics handling rather than Views using built-in XML animations. There may be a way to do it with XML, but I'm much more familiar with canvases. A very good place to see how this is handled in code is the Lunar Lander example game that comes with the SDK.

Roughly the steps you'll need to follow are:

  1. Put a custom view in the XML file, using something like <your.package.AnimatingView>, setting its size to fill-parent.

  2. Then define a AnimatingView class, which extends SurfaceView and implements SurfaceHolder.Callback. (This gives you access to the drawing Canvas immediately rather than by using the invalidate() method. This is important because invalidate() only refreshes when the thread is idle, e.g. at the end of the loop. To implement your animation, you need to have it drawing immediately.)

  3. You can then implement a loop which draws your moving image across the screen. The loop needs to start by drawing the whole background (because the canvas doesn't automatically get erased) and then draw the image at its new position based on the time that has passed. For example, if you want your animation to take 1 second to do, then you know that if 200ms have passed, the view should only have moved 200/1000, or 1/5, of the way from its starting position to the final position.

You can see some examples of what I mean in my other answers to animation questions: basic reply about the usefulness of using SurfaceView and and example of the loop to use. Note: the second question was about rotating, and hence some of the difficulties I talked about won't be relevant to you. Good luck!


With android:translationX and android:translationY

<RelativeLayout
        android:translationX="-600dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent">

I had a viewgroup with children and was dragging the view into the screen from the bottom - kind of like a drawer. I then would let go and if the viewgroup top margin were in the top half of the screen I would animate it to the top after the user released the touch.

When this happened the images in the viewgroup's children would get cropped during the animation but would then get shown after the animation.

The problem: viewgroup's height was wrap_content. I solved this by setting the height to a value that stretched off the screen before the animation started.

참고URL : https://stackoverflow.com/questions/2554871/android-how-to-position-view-off-screen

반응형