Описание программных компонентов

Паттерн MVVM (Model - View - ViewModel) основывается на разделении функциональной части приложения на три ключевых компонента:

¾ View - пользовательский интерфейс;

¾ Model - данные, которые используются в приложении;

¾ ViewModel - промежуточный слой между представлением и данными, который обеспечивает их взаимодействия.

Преимуществом использования данного паттерна является меньшая связанность между компонентами и разделение ответственности между ними. То есть Model отвечает за данные, View отвечает за графический интерфейс, а ViewModel - за логику приложения.

Легкость реализации паттерна MVVM в Android Studio стала возможной благодаря ранее рассмотренному механизму привязки.

В листинге 2.1 представлен файл build.gradle(Module: app) в нем описаны все библиотеки, используемые приложением RabbitChat.

Листинг 2.1

apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'

android {
   
compileSdkVersion 29
buildToolsVersion "29.0.3"

defaultConfig {
       
applicationId "com.example.rabbitchat"
   minSdkVersion 23
   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'
implementation 'com.google.firebase:firebase-database:19.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

implementation 'com.firebaseui:firebase-ui-database:6.2.0'
implementation 'com.google.android.material:material:1.0.0'
}

В листинге 2.2 представлен главный класс MainActivity. Именно он запускается первым. Он связан с представлением activity_main.xml, которое представлен в листинге 2.3. В activity_main.xml пользователь вводит псевдоним, по которому к нему следует обращаться, после чего входит в чат.

Листинг 2.2

package com.example.rabbitchat;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

private static int MAX_USERNAME_LENGTH = 20;

private Button btnSettings;
private EditText InputUserName;

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout. activity_main);

   btnSettings = findViewById(R.id. btnSettings);
   InputUserName = findViewById(R.id. InputUserName);

   btnSettings.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v) {

           if(checkingUsername(InputUserName) == true) return;

           Intent intent = new Intent(MainActivity.this, Chat.class);
           intent.putExtra("username", InputUserName.getText().toString());
           startActivity(intent);
       }
   });

}

 private boolean checkingUsername(EditText InputUserName) {

   if(InputUserName.length() > MAX_USERNAME_LENGTH) {
       Toast toast = Toast. makeText (getApplicationContext(),
               "Ваше имя привысило допустимую длинну (" + MAX_USERNAME_LENGTH +")." +
                       "\nВы ввели (" + InputUserName.length() + ").",
               Toast. LENGTH_SHORT);
       toast.setGravity(Gravity. CENTER, 0, 0);
       toast.show();
       return true;
   }

   if(InputUserName.length() == 0) {
       Toast toast = Toast. makeText (getApplicationContext(),
               "Вы не ввели свой псевдоним",
               Toast. LENGTH_SHORT);
       toast.setGravity(Gravity. CENTER, 0, 0);
         toast.show();
       return true;
   }
   return false;
}
}

Листинг 2.3

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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"
android:background="@color/HomeScreenStyle"
tools:context=".MainActivity"
android:orientation="vertical">

<EditText
   android:id="@+id/InputUserName"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_marginTop="200dp"
   android:layout_marginLeft="30dp"
   android:layout_marginRight="30dp"
   android:hint="@string/text_edit_setting"
   android:inputType="text"
   android:importantForAutofill="no" />

<Button
   android:id="@+id/btnSettings"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_marginTop="40dp"
   android:layout_marginStart="30dp"
   android:layout_marginEnd="30dp"
   android:textColor="@android:color/white"
   android:background="@color/colorPrimary"
     android:text="@string/text_button_setting" />
</LinearLayout>

В листинге 2.4 представлен класс данных Message. Этот класс используется для выборки данных из Firebase.

Листинг 2.4

package com.example.rabbitchat;

public class Message {
private String NAME;
private String MSG;
private String TIME;

Message() {}

Message(String NAME, String MSG, String TIME) {
   this.NAME = NAME;
   this.MSG = MSG;
   this.TIME = TIME;
}

public String getNAME() {
   return NAME;
}

public void setID(String messageNAME) {
   this.NAME = messageNAME;
}

public String getMSG() {
   return MSG;
}

public void setMSG(String messageMSG) {
   this.MSG = messageMSG;
}

public String getTIME() {
   return TIME;
}

public void setTIME(String messageTIME) {
   this.TIME = messageTIME;
}
}

В листинге 2.5 представлен класс ViewHolder. Этот класс используется для вывода данных в single_view_layout.xml. single_view_layout.xml используется для вывода каждого отдельного сообщения из базы данных, он представлен в листинге 2.6.

Листинг 2.5

package com.example.rabbitchat;

import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

public class ViewHolder extends RecyclerView.ViewHolder {

TextView messageViewName, messageViewText, messageViewTime;

public ViewHolder(@NonNull View itemView){
   super(itemView);

   messageViewName = itemView.findViewById(R.id. viewName);
   messageViewText = itemView.findViewById(R.id. viewText);
   messageViewTime = itemView.findViewById(R.id. viewTime);
}
}

Листинг 2.6

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp">

<TextView
   android:id="@+id/viewName"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_marginTop="10dp"
   android:textSize="16dp"
   android:textStyle="normal|bold" />

<TextView
   android:id="@+id/viewTime"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_marginTop="12dp"
   android:textSize="12dp"
   android:textStyle="normal|bold"
   android:layout_alignParentRight="true"/>

<TextView
   android:id="@+id/viewText"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_below="@id/viewName"
   android:textSize="14dp"
   android:textStyle="normal"/>
</RelativeLayout>

В листинге 2.7 представлен класс Chat. Именно с помощью этого класса выполняется отправка сообщщений, так же он отвечает за последовательное отображение сообщений из базы данных. Этот класс, как и класс MainActivity имеет свое представление оно называется activity_chat.xml оно представлено в листинге 2.8. В этом представлении пользователи просматривают сообщения из чата или печатают свои сообщения и отправляют их в Firebase.

Листинг 2.7

package com.example.rabbitchat;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Build;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class Chat extends AppCompatActivity {

private static int MAX_MESSAGE_LENGTH = 200;

private Button btnMSG;
private EditText InputText;
private String username;

DatabaseReference ref;

private FirebaseRecyclerOptions<Message> options;
private FirebaseRecyclerAdapter<Message, ViewHolder> adapter;

private RecyclerView recyclerView;

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout. activity_chat);

   username = getIntent().getStringExtra("username");

   InputText = findViewById(R.id. InputText);

   btnMSG = findViewById(R.id. btnMSG);

   final Date currentDate = new Date();
   final DateFormat timeFormat = new SimpleDateFormat("HH:mm dd.MM.yyyy", Locale. getDefault ());
   final String timeText = timeFormat.format(currentDate);

   ref = FirebaseDatabase. getInstance ().getReference().child("Messages");

   recyclerView = findViewById(R.id. recyclerView);
   recyclerView.setHasFixedSize(true);
   recyclerView.setLayoutManager(new LinearLayoutManager(this));

   btnMSG.setOnClickListener(new View.OnClickListener() {
       @RequiresApi(api = Build.VERSION_CODES. O)
       @Override
       public void onClick(View v) {

           if(checkingMessageLength(InputText) == true) return;

           String NAME = username;
           String MSG = InputText.getText().toString();
           String TIME = timeText;

           String key = ref.push().getKey();
           ref.child(key).child("NAME").setValue(NAME);
           ref.child(key).child("MSG").setValue(MSG);
           ref.child(key).child("TIME").setValue(TIME);

           InputText.setText("");
       }
   });

   options = new FirebaseRecyclerOptions.Builder<Message>().setQuery(ref, Message.class).build();
   adapter = new FirebaseRecyclerAdapter<Message, ViewHolder>(options) {
       @Override
       protected void onBindViewHolder(@NonNull ViewHolder viewHolder, int i, @NonNull Message message) {
           viewHolder.messageViewName.setText(message.getNAME());
           viewHolder.messageViewText.setText(message.getMSG());
           viewHolder.messageViewTime.setText(message.getTIME());
       }

       @NonNull
       @Override
       public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
           View v = LayoutInflater. from (parent.getContext()).inflate(R.layout. single_view_layout, parent, false);
           return new ViewHolder(v);
       }
   };

   adapter.startListening();

   recyclerView.setAdapter(adapter);
}

private boolean checkingMessageLength(EditText inputText) {

   if(InputText.length() > MAX_MESSAGE_LENGTH) {
       Toast toast = Toast. makeText (getApplicationContext(),
               "Ваше сообщение привысило допустимый лимит символов ("+ MAX_MESSAGE_LENGTH +")." +
                       "\nВы ввели (" + InputText.length() + ").",
               Toast. LENGTH_SHORT);
       toast.setGravity(Gravity. CENTER, 0, 0);
      toast.show();
       return true;
   }

   if(InputText.length() == 0) {
       Toast toast = Toast. makeText (getApplicationContext(),
               "Вы не ввели сообщение",
               Toast. LENGTH_SHORT);
       toast.setGravity(Gravity. CENTER, 0, 0);
       toast.show();
       return true;
   }
   return false;
}
}

Листинг 2.8.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
android:background="@color/HomeScreenStyle"
android:id="@+id/activity_main">

<androidx.recyclerview.widget.RecyclerView
   android:id="@+id/recyclerView"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:layout_weight="1"
   android:paddingBottom="16dp"/>

<EditText
   android:id="@+id/InputText"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:hint="@string/edit_text_hint"
   android:textSize="16sp"
   android:paddingBottom="10dp" />

<Button
   android:id="@+id/btnMSG"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:textSize="16sp"
   android:text="@string/send_button_name"
   android:textColor="@android:color/white"
   android:background="@color/colorPrimary"/>
</LinearLayout>












































































































































































































































Описание интерфейса

На рисунке 5 представлен ярлык приложения «RabbitChat».

Рисунок 5 - ярлык приложения "RabbitChat"

При входе в приложение «RabbitChat» появляется главная страница. На этой странице есть текстовое поле, в которое пользователь должен ввести свой псевдоним, и нажать на кнопку «Добавить». Если же пользователь просто нажмет кнопку «Добавить» не заполняя текстовое поле или превысит лимит символов, то появится сообщение, предупреждающее об этом. Вид главной странице представлен на рисунке 6.

Рисунок 6 - Главная страница приложения

После заполнения текстового поля и нажатия на кнопку на главной странице приложения происходит переход на страницу с чатом. На странице с чатом пользователь имеет возможность читать сообщения других пользователей, реализована прокрутка сообщений. Еще на этой странице есть текстовое поле позволяющее набирать сообщения, и кнопка «Отправить». Которая отправляет набранное пользователем сообщение в Firebase.

Страница чата представлена на рисунках 7, 8, и 9.

Рисунок 7 - Страница чата

Рисунок 8 - Набор сообщения на странице чата

Рисунок 9 - Отправка сообщения


 


ОЦЕНКА РЕАЛИЗАЦИИ

Приложение «RabbitChat» предоставляет пользователям возможность быстрого обмена информацией при помощи всемирной сети Интернет.

Данное приложение ориентированно на небольшие группы людей и организаций. Основной функцией приложения является возможность отправки и получения сообщений в режиме реального времени на большие расстояния.

Таким образом, приложение «RabbitChat» выполняет следующие функции:

1. Добавление сообщений в чат;

2. Просмотр сообщений из чата;

3. Обновление чата при добавлении нового сообщения в режиме реального времени;

4. Проверка текста сообщений перед отправкой.

Для установки приложения «RabbitChat» необходимо устройство с ОС Android версией не ниже, чем 4.1.

Сейчас происходит тестирование приложения ограниченной группой пользователей. По завершении тестирования, будет выполнено исправление ошибок, если таковые будут выявлены.

В результате будет получена стабильная версия программы, которую уже можно будет загрузить в магазин приложений Google Play.


 


ЗАКЛЮЧЕНИЕ

В современном мире налаживание коммуникаций и поддержание уже существующих связей является чуть-ли не самой важной задачей, для решения которой человечество тратит очень много времени и сил. Чтобы решить эту проблему было разработано множество различных сервисов. Самой удобной версией таких программ являются мобильные приложения, поскольку практически каждый человек имеет при себе смартфон. Неудивительно, что такие приложения пользуются большим спросом.

Определив, что ОС Android является одной из самых популярных среди операционных систем, что существует обилие условно-бесплатных инструментов для разработки приложений, мы установили, что ОС Android подходит для достижения поставленных целей. Это подтвердилось на практике после использования доступной на Android библиотеки Firebase.

В результате выполнения курсовой работы была выполнена работа по проектированию и разработке приложения «RabbitChat», была разработана концептуальная модель базы данных и создана база данных в Firebase.

Данное приложение реализует все поставленные задачи. Приложение будет полезно для людей, которым нужна возможность отправки и получения сообщений в режиме реального времени на большие расстояния.

Планируется дальнейшее развитие проекта – регистрация и авторизация, получение уведомлений, сортировка сообщений, поиск сообщений по дате и тексту из сообщения, создание своих чатов и приглашение в них других пользователей. Следовательно, приложение не утратит актуальности и будет в дальнейшем гораздо полезнее.


 



Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: