Кашина_РМП_ЛБ14_2
.docxМинистерство науки и высшего образования Российской Федерации Федеральное государственное бюджетное образовательное учреждение высшего образования
«Владимирский государственный университет
имени Александра Григорьевича и Николая Григорьевича Столетовых» (ВлГУ)
Колледж инновационных технологий и предпринимательства
КАФЕДРА ФИЗИКИ И ПРИКЛАДНОЙ МАТЕМАТИКИ
Лабораторная работа № 14_2
по МДК 01.03 «Разработка мобильных приложений»
на тему: «Боковое навигационное меню в Андроид.»
Выполнил
студент группы ИПсп-123
Кашина Д. А.
Принял
Красильщикова В.В.
Владимир, 2026 г.
Цель работы: научиться создавать боковое меню в среде разработки Android Studio.
Ход работы:
side_nav_bar.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="#FF6200EE"
android:endColor="#FF3700B3"
android:startColor="#FF9C27B0"
android:type="linear" />
</shape>
app_bar_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
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.Dark.ActionBar">
<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/ThemeOverlay.AppCompat.Light" />
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
nav_header_main.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="176dp"
android:background="@drawable/side_nav_bar"
android:gravity="bottom"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingBottom="16dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:contentDescription="Аватар"
android:src="@mipmap/ic_launcher_round" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:text="Навигационное меню"
android:textColor="#FFFFFF"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Выполнила Кашина Д. А"
android:textColor="#FFFFFF"
android:textSize="14sp" />
</LinearLayout>
activity_main_drawer.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_home"
android:icon="@android:drawable/ic_menu_compass"
android:title="Главная" />
<item
android:id="@+id/nav_playlist"
android:icon="@android:drawable/ic_media_play"
android:title="Плейлист" />
<item
android:id="@+id/nav_camera"
android:icon="@android:drawable/ic_menu_camera"
android:title="Камера" />
<item
android:id="@+id/nav_gallery"
android:icon="@android:drawable/ic_menu_gallery"
android:title="Галерея" />
<item
android:id="@+id/nav_calendar"
android:icon="@android:drawable/ic_menu_today"
android:title="Календарь" />
</group>
</menu>
menu_main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_about"
android:title="О приложении"
android:icon="@android:drawable/ic_menu_info_details"
app:showAsAction="never" />
<item
android:id="@+id/action_settings"
android:title="Настройки"
android:icon="@android:drawable/ic_menu_preferences"
app:showAsAction="never" />
</menu>
fragment_home.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:gravity="center"
android:orientation="vertical"
android:padding="16dp"
android:background="@android:color/white">
<!-- Заголовок -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Главный экран"
android:textSize="24sp"
android:textStyle="bold"
android:textColor="#FF6200EE"
android:layout_marginBottom="20dp"/>
<!-- Ваша картинка -->
<ImageView
android:id="@+id/iv_my_photo"
android:layout_width="250dp"
android:layout_height="250dp"
android:src="@drawable/img2"
android:scaleType="centerCrop"
android:contentDescription="Мое фото"
android:elevation="4dp" />
<!-- Текст с ФИО -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="Кашина Д. А."
android:textSize="20sp"
android:textStyle="bold"
android:textColor="#333333"/>
<!-- Дополнительная информация -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Группа ИПсп-123"
android:textSize="16sp"
android:textColor="#666666"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Работу выполнила Кашина Д."
android:textStyle="italic"
android:textColor="#FF6200EE"
android:textSize="18sp"/>
</LinearLayout>
fragment_playlist.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"
android:padding="16dp"
android:gravity="center_horizontal">
<TextView
android:id="@+id/tv_track_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="track1.mp3"
android:textSize="18sp"
android:textStyle="bold"
android:paddingBottom="12dp"/>
<ImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:src="@drawable/img1"
android:contentDescription="Обложка"
android:scaleType="centerCrop"/>
<SeekBar
android:id="@+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="16dp">
<ImageButton
android:id="@+id/btn_prev"
android:layout_width="64dp"
android:layout_height="64dp"
android:src="@android:drawable/ic_media_rew"
android:background="@android:color/transparent"
android:contentDescription="Назад"/>
<ImageButton
android:id="@+id/btn_play_pause"
android:layout_width="64dp"
android:layout_height="64dp"
android:src="@android:drawable/ic_media_play"
android:background="@android:color/transparent"
android:contentDescription="Играть/Пауза"/>
<ImageButton
android:id="@+id/btn_next"
android:layout_width="64dp"
android:layout_height="64dp"
android:src="@android:drawable/ic_media_ff"
android:background="@android:color/transparent"
android:contentDescription="Вперёд"/>
</LinearLayout>
</LinearLayout>
fragment_gallery.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"
android:padding="8dp">
<TextView
android:id="@+id/tv_gallery_empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="32dp"
android:text="Галерея пуста. Сделайте фото в разделе Камера."
android:textSize="16sp"
android:textColor="#888888"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_gallery"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
fragment_camera.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"
android:gravity="center"
android:padding="16dp">
<ImageView
android:id="@+id/iv_preview"
android:layout_width="300dp"
android:layout_height="300dp"
android:src="@android:drawable/ic_menu_camera"
android:scaleType="centerCrop"
android:contentDescription="Предпросмотр"/>
<Button
android:id="@+id/btn_take_photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Сделать фото"/>
<TextView
android:id="@+id/tv_camera_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Нажмите кнопку для съёмки"
android:textColor="#888888"/>
</LinearLayout>
fragment_calendar.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"
android:padding="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Выполнила Кашина Д. А"
android:textStyle="italic"
android:textColor="#FF6200EE"
android:textSize="16sp"
android:gravity="center"
android:paddingBottom="16dp" />
<CalendarView
android:id="@+id/calendarView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
item_photo.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="4dp">
<ImageView
android:id="@+id/iv_photo"
android:layout_width="150dp"
android:layout_height="150dp"
android:scaleType="centerCrop"
android:contentDescription="Фото"/>
</LinearLayout>
file_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path
name="my_photos"
path="photos/" />
</paths>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.drawerlayout.widget.DrawerLayout 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:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <include layout="@layout/app_bar_main" android:layout_width="match_parent" android:layout_height="match_parent" /> <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>
PhotoStore.java
package com.example.lab14_2;
import java.util.ArrayList;
import java.util.List;
public class PhotoStore {
private static PhotoStore instance;
private final List<String> photoPaths = new ArrayList<>();
private PhotoStore() {}
public static PhotoStore getInstance() {
if (instance == null) instance = new PhotoStore();
return instance;
}
public void addPhoto(String path) {
photoPaths.add(path);
}
public List<String> getPhotos() {
return photoPaths;
}
}
PhotoAdapter.java
package com.example.lab14_2;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class PhotoAdapter extends RecyclerView.Adapter<PhotoAdapter.PhotoViewHolder> {
private final List<String> photoPaths;
public PhotoAdapter(List<String> photoPaths) {
this.photoPaths = photoPaths;
}
@NonNull
@Override
public PhotoViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_photo, parent, false);
return new PhotoViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull PhotoViewHolder holder, int position) {
String path = photoPaths.get(position);
holder.imageView.setImageURI(Uri.parse(path));
}
@Override
public int getItemCount() {
return photoPaths.size();
}
static class PhotoViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
PhotoViewHolder(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.iv_photo);
}
}
}
HomeFragment.java
package com.example.lab14_2;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class HomeFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_home, container, false);
}
}
PlaylistFragment.java
package com.example.lab14_2;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class PlaylistFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_playlist, container, false);
}
}
GalleryFragment.java
package com.example.lab14_2;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class GalleryFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_gallery, container, false);
RecyclerView recycler = view.findViewById(R.id.recycler_gallery);
TextView tvEmpty = view.findViewById(R.id.tv_gallery_empty);
List<String> photos = PhotoStore.getInstance().getPhotos();
if (photos.isEmpty()) {
tvEmpty.setVisibility(View.VISIBLE);
recycler.setVisibility(View.GONE);
} else {
tvEmpty.setVisibility(View.GONE);
recycler.setVisibility(View.VISIBLE);
recycler.setLayoutManager(new GridLayoutManager(requireContext(), 2));
recycler.setAdapter(new PhotoAdapter(photos));
}
return view;
}
}
CameraFragment.java
package com.example.laba14_2;
import android.Manifest;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import androidx.fragment.app.Fragment;
import com.example.laba14_2.PhotoStore;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class CameraFragment extends Fragment {
private static final String TAG = "CameraFragment";
private ImageView ivPreview;
private TextView tvStatus;
private Uri photoUri;
private final ActivityResultLauncher<Uri> cameraLauncher =
registerForActivityResult(
new ActivityResultContracts.TakePicture(),
success -> {
if (success && photoUri != null) {
ivPreview.setImageURI(null);
ivPreview.setImageURI(photoUri);
PhotoStore.getInstance().addPhoto(photoUri.toString());
tvStatus.setText("Фото сохранено в галерею!");
} else {
tvStatus.setText("Фото не сделано");
}
}
);
private final ActivityResultLauncher<String> permissionLauncher =
registerForActivityResult(
new ActivityResultContracts.RequestPermission(),
granted -> {
if (granted) {
launchCamera();
} else {
tvStatus.setText("Разрешение на камеру отклонено");
}
}
);
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_camera, container, false);
ivPreview = view.findViewById(R.id.iv_preview);
tvStatus = view.findViewById(R.id.tv_camera_status);
Button btnTakePhoto = view.findViewById(R.id.btn_take_photo);
btnTakePhoto.setOnClickListener(v -> openCamera());
return view;
}
private void openCamera() {
if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.CAMERA)
== PackageManager.PERMISSION_GRANTED) {
launchCamera();
} else {
permissionLauncher.launch(Manifest.permission.CAMERA);
}
}
private void launchCamera() {
try {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault())
.format(new Date());
String fileName = "PHOTO_" + timeStamp + ".jpg";
File storageDir = new File(requireContext().getFilesDir(), "photos");
if (!storageDir.exists()) {
storageDir.mkdirs();
}
File photoFile = new File(storageDir, fileName);
photoUri = FileProvider.getUriForFile(
requireContext(),
"com.example.lab14_2.fileprovider",
photoFile
);
Log.d(TAG, "Launching camera with URI: " + photoUri);
cameraLauncher.launch(photoUri);
} catch (Exception e) {
tvStatus.setText("Ошибка: " + e.getMessage());
Log.e(TAG, "Error launching camera", e);
}
}
}
CalendarFragment.java
package com.example.laba14_2;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class CalendarFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_calendar, container, false);
}
}
MainActivity.java
package com.example.lab14_2;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
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 com.google.android.material.navigation.NavigationView;
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
private DrawerLayout drawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
drawerLayout = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this,
drawerLayout,
toolbar,
R.string.navigation_drawer_open,
R.string.navigation_drawer_close
);
drawerLayout.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
if (savedInstanceState == null) {
navigationView.setCheckedItem(R.id.nav_home);
if (getSupportActionBar() != null) {
getSupportActionBar().setTitle("Главная");
}
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, new HomeFragment())
.commit();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
Toast.makeText(this, "Настройки", Toast.LENGTH_SHORT).show();
return true;
} else if (id == R.id.action_about) {
Toast.makeText(this, "О приложении", Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
Fragment selectedFragment = null;
String title = "";
int id = item.getItemId();
if (id == R.id.nav_home) {
selectedFragment = new HomeFragment();
title = "Главная";
} else if (id == R.id.nav_playlist) {
selectedFragment = new PlaylistFragment();
title = "Плейлист";
} else if (id == R.id.nav_camera) {
selectedFragment = new CameraFragment();
title = "Камера";
} else if (id == R.id.nav_gallery) {
selectedFragment = new GalleryFragment();
title = "Галерея";
} else if (id == R.id.nav_calendar) {
selectedFragment = new CalendarFragment();
title = "Календарь";
}
if (selectedFragment != null) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, selectedFragment)
.commit();
if (getSupportActionBar() != null) {
getSupportActionBar().setTitle(title);
}
}
drawerLayout.closeDrawer(GravityCompat.START);
return true;
}
@Override
public void onBackPressed() {
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
}
Результат работы программы
Вывод: в ходе выполнения данной лабораторной работы была изучено создание бокового меню в среде разработки Android Studio.
