728x90
반응형
유튜브 앱처럼 동영상을 기본 모드와 소형 플레이어로 전환을 할 수 있고 pip모드처럼 소형 플레이어를 원하는 대로 배치할 수 있도록 했다.
하지만 이때 동영상을 구현할 때 videoView를 사용하면 오류가 나서 surfaceView를 사용했다.
1. activity_main.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
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:id="@+id/relativeLayout">
<Button
android:id="@+id/startButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="86dp"
android:layout_marginTop="645dp"
android:text="start" />
<Button
android:id="@+id/stopButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="243dp"
android:layout_marginTop="645dp"
android:text="stop" />
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="400px"
android:layout_height="200px"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="111dp"
android:layout_marginTop="217dp">
<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</RelativeLayout>
|
cs |
2, 31~34 - surfaceView를 원하는 곳에 배치하기 위해서 자유도가 높은 relativeLayout을 사용했고 layout_margin을 이용해서 위치를 설정할 것이다.
2. MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
package com.example.mediaplayervideoviewexamplewithrelativelayout;
import ...
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
RelativeLayout relativeLayout;
LinearLayout linearLayout;
int lastY, lastX, curY, curX;
int mpWidth;
int mpHeight;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
MediaPlayer mediaPlayer;
boolean isPIPMode = true;
boolean lastIsPIPMode = true;
Button startButton, stopButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
relativeLayout = (RelativeLayout)findViewById(R.id.relativeLayout);
linearLayout = (LinearLayout)findViewById(R.id.linearLayout);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(400, 200);
layoutParams.setMargins(100, 100, 0, 0);
linearLayout.setLayoutParams(layoutParams);
relativeLayout.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
if (layoutParams.topMargin <= 10){ //surfaceView를 위로 올렸을 때 이벤트를 설정한다.
isPIPMode = false;
RelativeLayout.LayoutParams notPIPLayoutParams = new RelativeLayout.LayoutParams(mpWidth, mpWidth/2); //크기를 꽉차게 만들어준다.
notPIPLayoutParams.setMargins(0, 0, 0, 0); //제일 위에 배치시켜준다.
linearLayout.setLayoutParams(notPIPLayoutParams);
lastIsPIPMode = isPIPMode;
} else {
isPIPMode = true;
linearLayout.setLayoutParams(layoutParams);
if (!lastIsPIPMode){ //mode가 바꼈을 때 터치하고 있는 위치로 소형 플레이어를 이동시킨다.
layoutParams.setMargins((int)event.getX() - 200, (int)event.getY() - 100, 0, 0);
}
lastIsPIPMode = isPIPMode;
}
if (action == MotionEvent.ACTION_DOWN) { //Margin에 좌표의 편차를 더해줘서 드레그하는 손에 따라서 소형 플레이어가 움직이도록 한다.
lastY = (int) event.getY();
lastX = (int) event.getX();
} else if(action == event.ACTION_MOVE && ((layoutParams.leftMargin < lastX && lastX < layoutParams.leftMargin + (isPIPMode?400:mpWidth)) && (layoutParams.topMargin < lastY && lastY < layoutParams.topMargin + (isPIPMode?400:mpWidth)/2))){
curY = (int)event.getY();
curX = (int)event.getX();
if ((layoutParams.leftMargin + (isPIPMode?400:mpWidth) >= mpWidth && curX - lastX <= 0) || (layoutParams.leftMargin <= 0 && curX - lastX >= 0) || (layoutParams.leftMargin + (isPIPMode?400:mpWidth) < mpWidth && layoutParams.leftMargin > 0))
{
layoutParams.setMargins(layoutParams.leftMargin + curX - lastX, layoutParams.topMargin, 0, 0);
linearLayout.setLayoutParams(layoutParams);
}
if ((layoutParams.topMargin + (isPIPMode?400:mpWidth)/2 >= mpHeight && curY - lastY <= 0) || (layoutParams.topMargin <= 0 && curY - lastY >= 0) || (layoutParams.topMargin + (isPIPMode?400:mpWidth)/2 < mpHeight && layoutParams.topMargin >0))
{
layoutParams.setMargins(layoutParams.leftMargin, layoutParams.topMargin + curY - lastY, 0, 0);
linearLayout .setLayoutParams(layoutParams);
}
lastX = curX;
lastY = curY;
}
return true;
}
});
surfaceView = (SurfaceView)findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
startButton = (Button)findViewById(R.id.startButton);
startButton.setOnClickListener(v -> {
if (!mediaPlayer.isPlaying()){
mediaPlayer.start();
}
});
stopButton = (Button)findViewById(R.id.stopButton);
stopButton.setOnClickListener(v -> {
if (mediaPlayer.isPlaying()){
mediaPlayer.stop();
try {
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
@Override
public void surfaceCreated(@NonNull SurfaceHolder holder) {
if (mediaPlayer == null) {
mediaPlayer = new MediaPlayer();
} else {
mediaPlayer.reset();;
}
try {
Uri uri = Uri.parse("android.resource://" + getPackageName() + "/raw/video");
mediaPlayer.setDataSource(this, uri);
mediaPlayer.setDisplay(surfaceHolder);
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) { }
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder holder) { }
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
mpWidth = relativeLayout.getWidth();
mpHeight = relativeLayout.getHeight();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mediaPlayer != null){
mediaPlayer.release();
}
}
}
|
cs |
3. 결과
728x90
반응형
'Android App' 카테고리의 다른 글
하단 선택바 (bottomNavigation, Fragment 전환) in Android Studio (0) | 2021.09.17 |
---|---|
외부저장소 동영상 플레이어 in Android Studio (0) | 2021.09.04 |
google map api 사용하기 in Android Studio (0) | 2021.09.03 |
더블클릭으로 앱 종료 in Android Studio (0) | 2021.08.31 |
mediaPlayer (mp3 재생) in Android Studio (0) | 2021.08.23 |