66

アプリケーションで単純なImageViewをアニメーション化しようとしていますが、画面の下部からスライドさせて、ビューの上部50ピクセルが画面の上部から外れる静止位置(最終位置など)に移動したいと考えています。 ImageViewのはXで-50pxである必要があります)。これを行うためにAbsoluteLayoutを使用しようとしましたが、これは実際にはImageViewの上位50ピクセルを切り取り、上位50ピクセルがレンダリングされないようにします。アニメーション中にImageViewの上部50ピクセルを表示/レンダリングしてから、画面から少し外して静止させる必要があります。私はそれを十分に説明したと思います。

これが私が現在レイアウトとスライドインアニメーションとして使用しているものです(これは現在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>

前もって感謝します。

4

6 に答える 6

33

実装が簡単なはずのこれに対する解決策を見つけました。これには、レイアウトの変更と、レイアウトを拡張するアクティビティが含まれます...以下を参照してください。

アクティビティ (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 秒でスライドインし、レイアウトの上部が実際には画面の上部から 50 ピクセル離れた場所 (つまりLL.getTop() = -50) で停止し、レイアウトの下部が画面の下部で停止します。画面(つまりLL.getBottom() = 530 = 480 + 50)。

于 2010-04-02T02:38:28.143 に答える
30

ビューを画面外に配置するには、次のコードを使用しました。

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 行目から 912行目を調べて、layoutParams を変更する必要がある理由を確認してください。

于 2012-04-19T06:46:28.000 に答える
9

Canvas;を使用してジャンプする場合、これは簡単に実行できます。それらは問題なく画面からの描画をサポートします。ただし、実装はより複雑になります。Viewカスタムを実装し、独自のアニメーションをコードで記述する必要があります。基本的に、これは、組み込みの XML アニメーションを使用したビューではなく、単純な 2D グラフィック処理に帰着します。XML でそれを行う方法はあるかもしれませんが、私はキャンバスの方がずっと詳しいです。これがコードでどのように処理されるかを確認するには、SDK に付属する Lunar Lander のサンプル ゲームを参照してください。

大まかに次の手順に従う必要があります。

  1. のようなものを使用してカスタム ビューを XML ファイルに配置し、<your.package.AnimatingView>そのサイズを fill-parent に設定します。

  2. 次に、AnimatingView クラスを定義しますextends SurfaceView and implements SurfaceHolder.CallbackCanvas(これにより、メソッドを使用するのではなく、すぐに描画にアクセスできますinvalidate()。これは重要です。invalidate() は、ループの最後など、スレッドがアイドル状態のときにのみ更新されるためです。アニメーションを実装するには、描画する必要があります。すぐに。)

  3. 次に、画面全体に動画を描画するループを実装できます。ループは背景全体を描画することから始めて (キャンバスは自動的に消去されないため)、経過時間に基づいて新しい位置に画像を描画する必要があります。たとえば、アニメーションに 1 秒かかるようにしたい場合、200 ミリ秒が経過した場合、ビューは開始位置から最終位置まで 200/1000、つまり 1/5 だけ移動する必要があることがわかっています。 .

アニメーションの質問に対する私の他の回答で、私が意味することのいくつかの例を見ることができます: SurfaceView を使用する有用性に関する基本的な回答と、使用するループの例. 注: 2 番目の質問はローテーションに関するものでした。したがって、私が話したいくつかの問題は、あなたには関係ありません。幸運を!

于 2010-04-01T13:40:51.040 に答える
2

私は子を持つビューグループを持っていて、ビューを下から画面にドラッグしていました - 引き出しのようなものです。次に、ビューグループの上部マージンが画面の上半分にある場合は、ユーザーがタッチを離した後、それを上部にアニメーション化します。

これが発生すると、ビューグループの子の画像はアニメーション中にトリミングされますが、アニメーションの後に表示されます。

問題: ビューグループの高さが wrap_content でした。アニメーションが始まる前に画面から伸びる値に高さを設定することで、これを解決しました。

于 2014-01-23T20:07:55.253 に答える