728x90
안녕하세요.
CoordinatorLayout과 BottomSheet를 사용해서 다음 동영상의 유투브 화면을 따라만들기 예제입니다.
먼저 오늘은 동영상 플레이어와 동영상 정보를 보여주는 바텀시트를 먼저 만들어보겠습니다.
동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.
1. Media3 ExoPlayer 의존성 추가
먼저 앱수준 build.gradle에 동영상 플레이어를 사용하기 위한 Media3 ExoPlayer 의존성을 최신버전으로 추가합니다.
implementation "androidx.media3:media3-exoplayer:1.4.0"
implementation "androidx.media3:media3-exoplayer-dash:1.4.0"
implementation "androidx.media3:media3-ui:1.4.0"
2. 바텀시트 배경 drawble 만들기
바텀시트를 둥근 모서리로 만들기 위해 drawble 폴더에 다음과 같이 xml 파일을 만듭니다.
white_round_top_border_20.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/white" />
<corners
android:topLeftRadius="20dp"
android:topRightRadius="20dp" />
</shape>
3. 메인 액티비티 레이아웃 작성하기
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/coordinator_layout"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="@color/black">
<!-- 동영상 뷰 -->
<androidx.media3.ui.PlayerView
android:id="@+id/player_view"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_gravity="top"
app:use_controller="true"
app:resize_mode="fit"/>
<!-- 정보 Bottom Sheet -->
<LinearLayout
android:id="@+id/info_bottom_sheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
android:background="@drawable/white_round_top_border_20"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
app:behavior_hideable="true"
app:behavior_peekHeight="360dp">
<!-- 드래그 핸들 -->
<com.google.android.material.bottomsheet.BottomSheetDragHandleView
android:id="@+id/drag_handle_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="동영상 제목"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="영상에 대한 설명 ~~"
android:layout_marginTop="8dp" />
<Button
android:id="@+id/button_show_comments"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="댓글 보기"
android:layout_marginTop="16dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="관련된 영상\n광고\n그외 기타등등\n"
android:layout_marginTop="8dp" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
4. 메인 액티비티 작성하기
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.media3.common.MediaItem;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.ui.PlayerView;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
public class MainActivity extends AppCompatActivity {
private BottomSheetBehavior<View> infoBottomSheetBehavior;
private PlayerView playerView;
private ExoPlayer player;
private GestureDetector gestureDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ExoPlayer 초기화
playerView = findViewById(R.id.player_view);
player = new ExoPlayer.Builder(this).build();
playerView.setPlayer(player);
// 동영상 설정
MediaItem mediaItem = MediaItem.fromUri("https://www.example.com/video.mp4"); // 재생할 동영상 주소
player.setMediaItem(mediaItem);
player.prepare();
player.play();
// 정보 Bottom Sheet 설정
View infoBottomSheet = findViewById(R.id.info_bottom_sheet);
infoBottomSheetBehavior = BottomSheetBehavior.from(infoBottomSheet);
infoBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
// GestureDetector 초기화 및 설정
gestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
// 위로 스와이프하면 정보 Bottom Sheet를 다시 확장
if (e2.getY() < e1.getY()) {
if (infoBottomSheetBehavior.getState() == BottomSheetBehavior.STATE_HIDDEN) {
infoBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
}
return super.onFling(e1, e2, velocityX, velocityY);
}
});
// 정보 Bottom Sheet 상태 변화 감지
infoBottomSheetBehavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) playerView.getLayoutParams();
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
// 정보 Bottom Sheet가 숨겨졌을 때 동영상 뷰를 화면 가운데로 이동
params.gravity = android.view.Gravity.CENTER_VERTICAL;
// 스크린 전체에서 터치 이벤트를 감지하여 GestureDetector에 전달
findViewById(R.id.coordinator_layout).setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
gestureDetector.onTouchEvent(event);
return true;
}
});
} else {
// 정보 Bottom Sheet가 보일 때 동영상 뷰를 위로 밀기
params.gravity = android.view.Gravity.TOP;
// 터치 이벤트 해제
findViewById(R.id.coordinator_layout).setOnTouchListener(null);
}
playerView.setLayoutParams(params);
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
// 필요한 경우 슬라이드 동작에 따라 애니메이션을 추가할 수 있습니다.
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
player.release(); // ExoPlayer 자원 해제
}
}
5. 시연영상
위 코드를 실행하면 다음과 같이 영상 정보 바텀시트가 사라지고 나타남에 따라 동영상 플레이어의 위치가 변경되는 것을 확인 할 수 있습니다.
동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.
다음 시간에는 댓글보기 버튼을 클릭시 댓글을 확인할 수 있는 바텀시트를 볼 수 있도록 구현해보겠습니다.
감사합니다~
'안드로이드 자바' 카테고리의 다른 글
| [JAVA][Android] 하나의 리사이클러뷰에 여러 타입의 뷰 추가하기 (Multi-View Type) (0) | 2024.07.28 |
|---|---|
| [JAVA][Android]항목 선택 다이얼로그 만들기 (0) | 2024.07.27 |
| [Java][Android] 암시적 인텐트 사용해서 웹 검색하기 (0) | 2024.07.25 |
| [Java][Android] DTO 객체를 사용하여 시간 최신 정렬하기 (2) | 2024.07.24 |
| [JAVA][Android] CalendarView, RecyclerView 를 사용하여 To-Do List 만들기 / 안드로이드 달력 사용하기 (3) | 2024.07.23 |