もう本当にAnmationを簡単に実装したい時は、これに限ると思ってます!
スケールを大きくする
// Scale Focusが当たった時やTapした時など
// XとYの大きさが100msかけて大きくなる
textView.animate().scaleX(2f).scaleY(2f).setDuration(1000);
ふわっと出す
// Splash向け 1200msかけて透明度が0になる 1が透明度なし 0が透明です
// 0.8fが80パーセントの透明度
textView.animate().alpha(0f).setDuration(1200);
SwipeRefreshLayoutを引っ張り更新の際にとかやると綺麗
// Viewの更新がかかった後など
listView.setAlpha(0f);
listView.animate().alpha(1f).setDuration(300);
移動
// 500msかけてxとyが100ピクセル移動する
textView.animate().x(100).y(100).setDuration(500);
回転する
// Rotation トーグルを回転させる時の動きなどに! 1000msかけて1回転する
// 180なら半回転
textView.animate().rotation(360).setDuration(1000);
Animationが始まった時や終わった時のリスナーをつける
// scaleがXとY二倍になった後
textView.animate().scaleX(2f).scaleY(2f).setDuration(1000).setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
textView.animate().scaleX(1f).scaleY(1f).setDuration(2000);
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
実際にアプリに組み込んでみるとこんな感じ
タップすると動画プレイヤーを大きくする・小さくするをします
scaleX scaleY x y setDuration alpha を使っています
Youtubeみたい!
※ 動画の再生には、ExoPlayerを使っています
ソースはこちら
import android.content.pm.ActivityInfo;
import android.databinding.DataBindingUtil;
import android.graphics.SurfaceTexture;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.FragmentActivity;
import android.view.TextureView;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.webkit.WebView;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.LoadControl;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
import com.google.android.exoplayer2.trackselection.AdaptiveVideoTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import java.util.Timer;
import java.util.TimerTask;
import jp.logiclogic.recycler_in_exoplayer.R;
import jp.logiclogic.recycler_in_exoplayer.databinding.ExoPlayerAnimationLayoutBinding;
/**
* Created by ueno-yuuhei on 2016/11/12.
*/
public class ExoPlayerAnimationActivity extends FragmentActivity implements TextureView.SurfaceTextureListener {
private ExoPlayerAnimationLayoutBinding binding; // DataBinging
private SimpleExoPlayer simpleExoPlayer; // ExoPlayer
private Timer playerTimer; // プレイヤー監視
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.exo_player_animation_layout);
// 横固定
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
// ステータスバー非表示
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
// ナビゲーションバー非表示
View decor = getWindow().getDecorView();
if (Build.VERSION.SDK_INT > 18) {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
} else if (Build.VERSION.SDK_INT > 15) {
decor.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN);
} else if (Build.VERSION.SDK_INT > 13) {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
} else {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
}
// ViewTreeObserverでプレイヤー領域の大きさを確保してから右下にAnimation
binding.textureViewArea.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (binding.textureViewArea.getWidth() > 0 && binding.textureViewArea.getWidth() > 0) {
binding.textureViewArea.animate()
.scaleX(0.3f)
.scaleY(0.3f)
.x((float) (binding.textureViewArea.getWidth() / 3))
.y((float) (binding.textureViewArea.getHeight() / 3))
.setDuration(100);
binding.playerTime.animate().setDuration(100).alpha(0f);
binding.textureViewArea.setTag(true);
if (Build.VERSION.SDK_INT >= 16) {
binding.textureViewArea.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
binding.textureViewArea.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
}
});
binding.textureView.setSurfaceTextureListener(this);
binding.textureViewArea.setTag(true);
// プレイヤー領域をTapしたらAnimationで右下に動くように
binding.textureViewArea.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
boolean toggle = (Boolean) view.getTag();
if (toggle) {
binding.textureViewArea.animate().scaleX(1f).scaleY(1f).x(0).y(0).setDuration(100);
binding.playerTime.animate().setDuration(100).alpha(1f);
} else {
binding.textureViewArea.animate().scaleX(0.3f).scaleY(0.3f)
.x((float) (binding.textureViewArea.getWidth() / 3))
.y((float) (binding.textureViewArea.getHeight() / 3))
.setDuration(100);
binding.playerTime.animate().setDuration(100).alpha(0f);
}
view.setTag(!toggle);
}
});
}
@Override
protected void onResume() {
super.onResume();
if (simpleExoPlayer != null) {
starPlayerTimer();
simpleExoPlayer.setPlayWhenReady(true);
}
}
@Override
protected void onPause() {
super.onPause();
stopPlayerTimer();
if (simpleExoPlayer != null) {
simpleExoPlayer.setPlayWhenReady(false);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
}
// 秒数をセット
private void starPlayerTimer() {
stopPlayerTimer();
playerTimer = new Timer();
playerTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
binding.playerTime.post(new Runnable() {
@Override
public void run() {
int duration = (int) (simpleExoPlayer.getDuration() / 1000);
int current = (int) (simpleExoPlayer.getCurrentPosition() / 1000);
String time = getMinuteSecond(current) + " / " + getMinuteSecond(duration);
binding.playerTime.setText(time);
binding.imageTime.setText(time);
}
});
}
}, 1000, 1000);
}
private String getMinuteSecond(int totalSecond) {
int minute = totalSecond / 60;
int second = totalSecond % 60;
return String.format("%02d", minute) + ":" + String.format("%02d", second);
}
private void stopPlayerTimer() {
if (playerTimer != null) {
playerTimer.purge();
playerTimer.cancel();
playerTimer = null;
}
}
// ------ ExoPlayer ------
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
Handler mainHandler = new Handler();
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveVideoTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector = new DefaultTrackSelector(mainHandler, videoTrackSelectionFactory);
LoadControl loadControl = new DefaultLoadControl();
simpleExoPlayer = ExoPlayerFactory.newSimpleInstance(getApplicationContext(), trackSelector, loadControl);
simpleExoPlayer.setVideoTextureView(binding.textureView);
DefaultBandwidthMeter defaultBandwidthMeter = new DefaultBandwidthMeter();
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this,
com.google.android.exoplayer2.util.Util.getUserAgent(this, new WebView(getApplicationContext()).getSettings().getUserAgentString()), defaultBandwidthMeter);
simpleExoPlayer.prepare(getHlsMediaSource("http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8", dataSourceFactory, mainHandler));
simpleExoPlayer.setPlayWhenReady(true);
starPlayerTimer();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
private HlsMediaSource getHlsMediaSource(String videoUrl, DataSource.Factory dataSourceFactory, Handler mainHandler) {
return new HlsMediaSource(Uri.parse(videoUrl),
dataSourceFactory,
mainHandler, null);
}
// ------ ExoPlayer ------
}
レイアウトファイル
<layout>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#222"
tools:context=".activity.ExoPlayerActivity">
<TextView
android:id="@+id/image_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|right"
android:layout_margin="16dp"
android:textColor="#FFF"
android:textSize="16sp" />
<FrameLayout
android:id="@+id/texture_view_area"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextureView
android:id="@+id/texture_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/player_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="16dp"
android:textColor="#FFF"
android:textSize="16sp" />
</FrameLayout>
</FrameLayout>
</layout>