Android --如何将视图定位到屏幕外?

ht4b089n  于 2022-12-28  发布在  Android
关注(0)|答案(6)|浏览(262)

我尝试在应用程序中为一个简单的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>
wz1wpwve

wz1wpwve1#

相反,我们可以简单地给layout_margin(上/左/右/下)给予负值,例如:如果您希望视图从屏幕顶部关闭,可以指定

android:layout_marginTop="-40dp"
idfiyjo8

idfiyjo82#

我想出了一个解决方案,应该很容易实现。它涉及到修改布局和活动膨胀布局...见下文:
活动(快速播放. 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));
    }
}

新建线性布局(自定义线性布局. 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秒内滑入,然后休息,布局的顶部实际上是屏幕顶部的50 px(iidoEe. LL.getTop() = -50),布局的底部休息在屏幕底部(iidoEe. LL.getBottom() = 530 = 480 + 50)。

wooyq4lh

wooyq4lh3#

为了将视图定位到屏幕外,我使用了以下代码:

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);

此代码将myView定位在屏幕外amountOffscreen的位置,在本例中,将80%的视图定位在屏幕外,只留下20%的视图在屏幕上。
请勿直接使用layout()方法- Android将在后续调用中随机使您的视图无效,并且只有layoutParams在无效调用中保持不变。如果您感兴趣,请查看904 to 912 of this file行,了解您为什么必须修改layoutParams。

up9lanfz

up9lanfz4#

如果您打算直接使用Canvas,这很容易做到;那些支持在屏幕外绘图的应用程序没有任何问题。但是,实现起来会更复杂。你需要实现一个定制的View,并用代码编写自己的动画。本质上,这归结为简单的2D图形处理,而不是使用内置XML动画的视图。也许有一种方法可以用XML来实现这一点,但我更熟悉画布。一个很好的地方,看看这是如何在代码中处理的是月球登陆者的例子游戏,与SDK。
您需要遵循的步骤大致如下:
1.在XML文件中放置一个自定义视图,使用类似<your.package.AnimatingView>的命令,将其大小设置为fill-parent。
1.然后定义一个AnimatingView类extends SurfaceView and implements SurfaceHolder.Callback。(这使您可以立即访问绘图Canvas,而不是使用invalidate()方法。这一点很重要,因为invalidate()只在线程空闲时刷新,例如在循环结束时。要实现动画,您需要立即绘制它。)
1.然后你可以实现一个循环,在屏幕上绘制移动的图像。这个循环需要从绘制整个背景开始(因为画布不会自动擦除),然后根据经过的时间在新位置绘制图像。例如,如果您希望动画花费1秒完成,则您知道如果经过200毫秒,视图应当仅移动了从其起始位置到最终位置的路径的200/1000或1/5。
你可以在我对动画问题的其他回答中看到一些例子:关于usefulness of using SurfaceView和和example of the loop to use的基本回复。注意:第二个问题是关于轮换的,所以我讲的一些困难与你无关。祝你好运!

mwecs4sa

mwecs4sa5#

使用android:translationXandroid: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">
dkqlctbz

dkqlctbz6#

我有一个有孩子的视图组,我把视图从底部拖到屏幕上--有点像一个抽屉。然后我松开手,如果视图组的顶部边距在屏幕的上半部分,我会在用户松开触摸后将其动画化到顶部。
发生这种情况时,视图组的子视图中的图像将在动画期间被裁剪,但在动画之后显示。
问题是:视图组的高度是wrap_content,我通过将高度设置为在动画开始之前拉伸到屏幕之外的值来解决这个问题。

相关问题