오늘이라도
[Android] 23. Navigation Drawer / 오디오 재생, 정지, 일시정지, 재시작 본문
취업성공패키지 SW 개발자 교육/Android
[Android] 23. Navigation Drawer / 오디오 재생, 정지, 일시정지, 재시작
upcake_ 2020. 6. 9. 10:15반응형
https://github.com/upcake/Class_Examples
교육 중에 작성한 예제들은 깃허브에 올려두고 있습니다.
gif 파일은 클릭해서 보는 것이 정확합니다.
- Navigation Drawer -
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.example.my31_navigationdrawer"
minSdkVersion 16
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'com.android.support:design:29.0.0'
}
▲build.gradle(:app)
<?xml version="1.0" encoding="utf-8"?>
<!--화면 전체 : drawerLayout-->
<androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/drawerLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/Widget.AppCompat.Toolbar" />
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
<!--layout_gravity= bottom|end 두개 속성을 동시에 지정 가능-->
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@android:drawable/ic_dialog_email"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<!--실질적으로 보여지는 네비게이션 뷰-->
<!--헤더뷰와 아이템을 찾아서 사용한다-->
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer"/>
</androidx.drawerlayout.widget.DrawerLayout>
▲activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="navigation_view">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_home"
android:icon="@android:drawable/ic_menu_camera"
android:title="Home" />
<item
android:id="@+id/nav_gallery"
android:icon="@android:drawable/ic_menu_gallery"
android:title="Gallery" />
<item
android:id="@+id/nav_slideshow"
android:icon="@android:drawable/ic_menu_slideshow"
android:title="Slideshow" />
<item
android:id="@+id/nav_tools"
android:icon="@android:drawable/ic_menu_manage"
android:title="Tools" />
</group>
<item
android:id="@+id/communicate"
android:title="Communicate"
android:visible="false">
<!--처음엔 안보이게 설정-->
<menu>
<item
android:id="@+id/nav_share"
android:icon="@android:drawable/ic_menu_share"
android:title="Share" />
<item
android:id="@+id/nav_send"
android:icon="@android:drawable/ic_menu_send"
android:title="Send" />
</menu>
</item>
</menu>
▲activity_main_drawer.xml
<resources>
<!-- Base application theme. -->
<!--NoActionBar로 바꾸면 상단에 액션바가 사라짐-->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
▲styles.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/headerLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="176dp"
android:background="@drawable/side_nav_bar"
android:gravity="bottom"
android:orientation="vertical"
android:padding="16dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<ImageView
android:id="@+id/loginImage"
android:layout_width="50dp"
android:layout_height="50dp"
android:contentDescription="Navigation Header"
android:paddingTop="8dp"
android:src="@mipmap/ic_launcher_round" />
<TextView
android:id="@+id/loginID"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:text="Android Studio"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
<TextView
android:id="@+id/loginStr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="android.studio@android.com" />
</LinearLayout>
▲nav_header_main.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="135"
android:centerColor="#009688"
android:endColor="#00695C"
android:startColor="#4DB6AC"
android:type="linear" />
</shape>
▲side_nav_bar.xml
package com.example.my31_navigationdrawer;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.navigation.NavigationView;
import com.google.android.material.snackbar.Snackbar;
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
Toolbar toolbar;
Fragment1 fragment1;
Fragment2 fragment2;
Fragment3 fragment3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawerLayout = findViewById(R.id.drawerLayout);
//string.xml에 사용할 스트링을 미리 작성해두고 그 주소(int 타입)을 가져다 사용한다.
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar,
R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawerLayout.addDrawerListener(toggle);
toggle.syncState();
//프래그먼트
fragment1 = new Fragment1();
fragment2 = new Fragment2();
fragment3 = new Fragment3();
getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment1).commit();
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
/*
//방법 1. setNavigationItemSelectedListener(new O) ▶ 자동 완성
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
return false;
}
});
*/
/*----------------------헤드 드로어에 로그인 정보 표시하기-------------------------*/
String loginID = "ASDF";
//헤더의 0번지 뷰에 접근한다
View headerView = navigationView.getHeaderView(0);
//헤더뷰에 id로 접근하면 에러가 나온다.
//View headerView = navigationView.findViewById(R.id.headerLayout);
//헤더 뷰의 객체 초기화
ImageView loginImage = headerView.findViewById(R.id.loginImage);
TextView navLoginID = headerView.findViewById(R.id.loginID);
//ID와 이미지를 로그인된 ID와 이미지로 바꾸기
navLoginID.setText("반갑습니다 " + loginID + "님");
loginImage.setImageResource(R.drawable.dream01);
//로그인 ID가 있으면 커뮤니케이트 메뉴가 보이게 설정
if(loginID != null) {
navigationView.getMenu().findItem(R.id.communicate).setVisible(true);
}
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_SHORT).setAction("Action", null).show();
}
});
}
//방법 2. 메인액티비티 implements NavigationView.OnNavigationItemSelectedListener ▶ implements methods
//navigationView 객체를 초기화하고 navigationView.setNavigationItemSelectedListener(this);
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
int selectedItemId = menuItem.getItemId();
if (selectedItemId == R.id.nav_home) {
Toast.makeText(this, "첫 번째 메뉴 선택", Toast.LENGTH_SHORT).show();
onFragmentSelected(0, null);
} else if (selectedItemId == R.id.nav_gallery) {
Toast.makeText(this, "두 번째 메뉴 선택", Toast.LENGTH_SHORT).show();
onFragmentSelected(1, null);
} else if (selectedItemId == R.id.nav_slideshow) {
Toast.makeText(this, "세 번째 메뉴 선택", Toast.LENGTH_SHORT).show();
onFragmentSelected(2, null);
} else if (selectedItemId == R.id.nav_tools) {
Toast.makeText(this, "네 번째 메뉴 선택", Toast.LENGTH_SHORT).show();
onFragmentSelected(3, null);
} else if (selectedItemId == R.id.nav_share) {
Toast.makeText(this, "다섯 번째 메뉴 선택", Toast.LENGTH_SHORT).show();
onFragmentSelected(4, null);
} else if (selectedItemId == R.id.nav_send) {
Toast.makeText(this, "여섯 번째 메뉴 선택", Toast.LENGTH_SHORT).show();
onFragmentSelected(5, null);
}
//드로어 닫기
DrawerLayout drawerLayout = findViewById(R.id.drawerLayout);
drawerLayout.closeDrawer(GravityCompat.START);
return true;
} //onNavigationItemSelected()
public void onFragmentSelected(int position, Bundle bundle) {
Fragment curFragment = null;
if (position == 0) {
curFragment = fragment1;
toolbar.setTitle("첫 번째 화면");
} else if (position == 1) {
curFragment = fragment2;
toolbar.setTitle("두 번째 화면");
} else if (position == 2) {
curFragment = fragment3;
toolbar.setTitle("세 번째 화면");
} else if (position == 3) {
curFragment = fragment1;
toolbar.setTitle("네 번째 화면");
} else if (position == 4) {
curFragment = fragment2;
toolbar.setTitle("다섯 번째 화면");
} else if (position == 5) {
curFragment = fragment3;
toolbar.setTitle("여섯 번째 화면");
}
getSupportFragmentManager().beginTransaction().replace(R.id.container, curFragment).commit();
} //onFragmentSelect()
//뒤로가기 버튼이 눌렸을때 작동하는 메서드
@Override
public void onBackPressed() {
DrawerLayout drawerLayout = findViewById(R.id.drawerLayout);
if(drawerLayout.isDrawerOpen(GravityCompat.START)) { // 드로어가 열려있다면
drawerLayout.closeDrawer(GravityCompat.START); // 드로어를 닫는다.
} else {
super.onBackPressed();
}
} //onBackPressed()
}
▲MainActivity.java
<resources>
<string name="app_name">My31_NavigationDrawer</string>
<string name="navigation_drawer_open">Open Navigation Drawer</string>
<string name="navigation_drawer_close">Close Navigation Drawer</string>
</resources>
▲strings.xml
- 오디오 재생, 정지, 일시정지, 재시작 -
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="재생"
android:textSize="24sp" />
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="정지"
android:textSize="24sp" />
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="일시정지"
android:textSize="24sp" />
<Button
android:id="@+id/button4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="재시작"
android:textSize="24sp" />
</LinearLayout>
▲activity_main.xml
package com.example.my32_audioplayer;
import androidx.appcompat.app.AppCompatActivity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
//외부 URL에서 가져올 경우
String AUDIO_URL = "http://sites.google.com/site/ubiaccessmobile/sample_audio.amr";
MediaPlayer mediaPlayer;
int position = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//버튼 객체 초기화
Button btnStart = findViewById(R.id.button1);
Button btnStop = findViewById(R.id.button2);
Button btnPause = findViewById(R.id.button3);
Button btnResume = findViewById(R.id.button4);
//시작 버튼 기능 추가
btnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
playAudio(AUDIO_URL);
// playAudioInnerProject(R.raw.m01);
Toast.makeText(MainActivity.this, "재생 시작!", Toast.LENGTH_SHORT).show();
}
});
//정지 버튼 기능 추가
btnStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mediaPlayer != null) { // mediaPlayer가 재생중일 때
mediaPlayer.stop();
Toast.makeText(MainActivity.this, "음악 정지!", Toast.LENGTH_SHORT).show();
}
}
});
//일시정지 버튼 기능 추가
btnPause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mediaPlayer != null) {
position = mediaPlayer.getCurrentPosition();
mediaPlayer.pause();
Toast.makeText(MainActivity.this, "음악 일시정지! : " + position, Toast.LENGTH_SHORT).show();
}
}
});
//재시작 버튼 기능 추가
btnResume.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mediaPlayer != null && !mediaPlayer.isPlaying()) { // 미디어 플레이어에 재생 흔적이 있으면서 재생중이 아닐때
mediaPlayer.start();
mediaPlayer.seekTo(position);
Toast.makeText(MainActivity.this, "음악 재시작! : " + position, Toast.LENGTH_SHORT).show();
}
}
});
}
private void playAudio(String audio_url) {
killMediaPlayer();
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(audio_url);
mediaPlayer.prepare();
mediaPlayer.start();
} catch (Exception e) {
e.printStackTrace();
e.getMessage(); //에러 발생시 메세지 출력
}
} //playAudio()
private void playAudioInnerProject(int resId) {
killMediaPlayer();
try {
// mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.m01);
mediaPlayer.start();
} catch (Exception e) {
e.printStackTrace();
e.getMessage(); //에러 발생시 메세지 출력
}
} //playAudio()
//기존의 재생되고 있는 미디어플레이어를 제거하는 메서드
private void killMediaPlayer() {
if(mediaPlayer != null) {
mediaPlayer.release();
}
} //killMediaPlayer()
//어플리케이션이 정지될 경우 작동하는 메서드
@Override
protected void onStop() {
super.onStop();
killMediaPlayer();
} //onStop()
}
▲MainActivity.java
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.my32_audioplayer">
<!--권한 설정-->
<uses-permission android:name="android.permission.INTERNET" />
<!--Cleartext HTTP traffic to sites.google.com not permitted-->
<!--IOException 발생시 android:usesCleartextTraffic="true" 추가할 것-->
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
▲AndroidManifest.xml
반응형