diff --git a/.gitignore b/.gitignore index 48bb0d7..43a71ba 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,4 @@ /build /captures .externalNativeBuild -/.idea/ +/.idea/ \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 3710062..a16ef66 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,12 +16,18 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } + compileOptions { + targetCompatibility 1.8 + sourceCompatibility 1.8 + } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' + implementation 'com.android.support:recyclerview-v7:28.0.0' + implementation 'de.hdodenhof:circleimageview:3.0.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 625f38c..9fe176b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,14 +8,19 @@ android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme"> - + android:theme="@style/Theme.AppCompat.DayNight.NoActionBar"> + + + + \ No newline at end of file diff --git a/app/src/main/java/ru/ok/technopolis/students/MainActivity.java b/app/src/main/java/ru/ok/technopolis/students/MainActivity.java index adde500..3e9b1c2 100644 --- a/app/src/main/java/ru/ok/technopolis/students/MainActivity.java +++ b/app/src/main/java/ru/ok/technopolis/students/MainActivity.java @@ -1,14 +1,227 @@ package ru.ok.technopolis.students; +import android.content.Context; +import android.os.Vibrator; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.EditText; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +import de.hdodenhof.circleimageview.CircleImageView; public class MainActivity extends AppCompatActivity { + private List students = new ArrayList<>(); + private StudentsAdapter studentsAdapter; + + private CircleImageView studentAvatar; + private EditText studentSecondName; + private EditText studentFirstName; + private CheckBox maleGender; + + private Button addStudentButton; + private Button saveStudentButton; + private Button removeStudentButton; + + private Student activeStudent; + private int newPhoto = -1; + private boolean prevGender; + + private int[] femalesPhoto = new int[3]; + private int[] malesPhoto = new int[3]; + + private Random random = new Random(); + private Vibrator vibe; + private Animation shakeAnimations; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); + setupPhotos(); + generateStudentsList(); + setupRecyclerView(); + + vibe = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); + shakeAnimations = AnimationUtils.loadAnimation(this, R.anim.shake); + + studentAvatar = findViewById(R.id.student_profile__avatar); + studentSecondName = findViewById(R.id.student_profile__second_name); + studentFirstName = findViewById(R.id.student_profile__first_name); + + maleGender = findViewById(R.id.student_profile__male_gender); + maleGender.setOnCheckedChangeListener((compoundButton, isMaleGender) -> { + if(activeStudent != null) { + if (prevGender != isMaleGender){ + prevGender = isMaleGender; + newPhoto = (isMaleGender) + ? malesPhoto[random.nextInt(3)] + : femalesPhoto[random.nextInt(3)]; + studentAvatar.setImageResource(newPhoto); + } else { + studentAvatar.setImageResource(activeStudent.getPhoto()); + } + + } + }); + + addStudentButton = findViewById(R.id.student_list__button_add); + addStudentButton.setOnClickListener(view -> { + setEnabledField(true); + clearFields(); + addStudentButton.setEnabled(false); + int photo = femalesPhoto[random.nextInt(3)]; + activeStudent = new Student(photo); + studentAvatar.setImageResource(photo); + }); + + saveStudentButton = findViewById(R.id.student_profile__buttons__save); + saveStudentButton.setOnClickListener(view -> addNewStudent()); + + removeStudentButton = findViewById(R.id.student_profile__buttons__remove); + removeStudentButton.setOnClickListener(view -> removeStudent()); + + setEnabledField(false); + } + + private void clearFields() { + activeStudent = null; + studentAvatar.setImageBitmap(null); + maleGender.setChecked(false); + studentSecondName.setText(""); + studentFirstName.setText(""); + } + + private void setDefaultValues(){ + clearFields(); + addStudentButton.setEnabled(true); + setEnabledField(false); + studentsAdapter.removeHighlight(); + prevGender = false; + newPhoto = -1; + } + + private void setEnabledField(boolean enabled){ + studentAvatar.setEnabled(enabled); + studentSecondName.setEnabled(enabled); + studentFirstName.setEnabled(enabled); + maleGender.setEnabled(enabled); + saveStudentButton.setEnabled(enabled); + removeStudentButton.setEnabled(enabled); + } + + private void addNewStudent() { + String secondName = studentSecondName.getText() != null + ? studentSecondName.getText().toString().trim() + : ""; + String firstName = studentFirstName.getText() != null + ? studentFirstName.getText().toString().trim() + : ""; + boolean isMale = maleGender.isChecked(); + + if (secondName.equals("") || firstName.equals("")) { + if (secondName.equals("")) { + studentSecondName.startAnimation(shakeAnimations); + } + if (firstName.equals("")) { + studentFirstName.startAnimation(shakeAnimations); + } + if (vibe != null) { + vibe.vibrate(100); + } + } else { + activeStudent.setFirstName(firstName); + activeStudent.setSecondName(secondName); + activeStudent.setMaleGender(isMale); + if (newPhoto != -1){ + activeStudent.setPhoto(newPhoto); + } + if (!students.contains(activeStudent)) { + students.add(activeStudent); + } + Collections.sort(students); + studentsAdapter.notifyDataSetChanged(); + setDefaultValues(); + } + } + + private void removeStudent() { + students.remove(activeStudent); + studentsAdapter.notifyDataSetChanged(); + setDefaultValues(); + } + + private void setupRecyclerView() { + RecyclerView recyclerView = findViewById(R.id.student_list__body); + studentsAdapter = new StudentsAdapter(students, this::onStudentClick); + recyclerView.setAdapter(studentsAdapter); + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); + recyclerView.setLayoutManager(linearLayoutManager); } + private void onStudentClick(Student student) { + setEnabledField(true); + addStudentButton.setEnabled(true); + prevGender = false; + newPhoto = -1; + activeStudent = student; + studentAvatar.setImageResource(activeStudent.getPhoto()); + studentSecondName.setText(activeStudent.getSecondName()); + studentFirstName.setText(activeStudent.getFirstName()); + prevGender = activeStudent.isMaleGender(); + maleGender.setChecked(activeStudent.isMaleGender()); + } + + private void setupPhotos() { + femalesPhoto[0] = R.drawable.female_1; + femalesPhoto[1] = R.drawable.female_2; + femalesPhoto[2] = R.drawable.female_3; + arrayShuffle(femalesPhoto); + malesPhoto[0] = R.drawable.male_1; + malesPhoto[1] = R.drawable.male_2; + malesPhoto[2] = R.drawable.male_3; + arrayShuffle(malesPhoto); + } + + private void generateStudentsList() { + for (int i = 0; i < 3; i++) { + switch (i) { + case 0: + students.add(new Student("Иван", "Иванов", true, malesPhoto[random.nextInt(3)])); + students.add(new Student("Анастасия", "Медведева", false, femalesPhoto[random.nextInt(3)])); + break; + + case 1: + students.add(new Student("Петр", "Петров", true, malesPhoto[random.nextInt(3)])); + students.add(new Student("Валерия", "Прокофьева", false, femalesPhoto[random.nextInt(3)])); + break; + + case 2: + students.add(new Student("Денис", "Денисов", true, malesPhoto[random.nextInt(3)])); + students.add(new Student("Александра", "Волкова", false, femalesPhoto[random.nextInt(3)])); + break; + } + } + Collections.sort(students); + } + + private static void arrayShuffle (int[] arr) { + Random random = new Random(); + for (int i=0; i < arr.length; i++) { + int randomPosition = random.nextInt(arr.length); + int temp = arr[i]; + arr[i] = arr[randomPosition]; + arr[randomPosition] = temp; + } + } } diff --git a/app/src/main/java/ru/ok/technopolis/students/Student.java b/app/src/main/java/ru/ok/technopolis/students/Student.java index 7be4d10..87f4d26 100644 --- a/app/src/main/java/ru/ok/technopolis/students/Student.java +++ b/app/src/main/java/ru/ok/technopolis/students/Student.java @@ -1,6 +1,8 @@ package ru.ok.technopolis.students; -public class Student { +import android.support.annotation.NonNull; + +public class Student implements Comparable { private String firstName; private String secondName; @@ -14,6 +16,10 @@ public Student(String firstName, String secondName, boolean maleGender, int phot this.photo = photo; } + public Student(int photo) { + this.photo = photo; + } + public String getFirstName() { return firstName; } @@ -45,4 +51,13 @@ public int getPhoto() { public void setPhoto(int photo) { this.photo = photo; } + + @Override + public int compareTo(@NonNull Student student) { + int res = secondName.toLowerCase().compareTo(student.getSecondName().toLowerCase()); + if (res != 0) { + return res; + } + return firstName.toLowerCase().compareTo(student.getFirstName().toLowerCase()); + } } diff --git a/app/src/main/java/ru/ok/technopolis/students/StudentsAdapter.java b/app/src/main/java/ru/ok/technopolis/students/StudentsAdapter.java new file mode 100644 index 0000000..d0340b9 --- /dev/null +++ b/app/src/main/java/ru/ok/technopolis/students/StudentsAdapter.java @@ -0,0 +1,87 @@ +package ru.ok.technopolis.students; + +import android.graphics.Color; +import android.support.annotation.NonNull; +import android.support.v4.content.ContextCompat; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import java.util.List; + +public class StudentsAdapter extends RecyclerView.Adapter{ + + private final List students; + private final Listener onStudentClickListener; + + private int selectedStudent = -1; + + public StudentsAdapter(List students, Listener onStudentClickListener) { + this.students = students; + this.onStudentClickListener = onStudentClickListener; + } + + public void removeHighlight() { + selectedStudent = -1; + notifyItemChanged(selectedStudent); + } + + @NonNull + @Override + public StudentViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { + View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.student_item, viewGroup, false); + return new StudentViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull StudentViewHolder viewHolder, int i) { + Student movie = students.get(i); + viewHolder.bind(movie); + viewHolder.itemView.setTag(movie); + + viewHolder.itemView.setSelected(selectedStudent == i); + + if(selectedStudent == i){ + viewHolder.itemView.setBackgroundColor(ContextCompat.getColor(viewHolder.itemView.getContext(), R.color.lightGray)); + } else { + viewHolder.itemView.setBackgroundColor(Color.WHITE); + } + } + + @Override + public int getItemCount() { + return students.size(); + } + + final class StudentViewHolder extends RecyclerView.ViewHolder{ + + private final TextView nameTextView; + private final ImageView avatarImageView; + + private StudentViewHolder(@NonNull View itemView) { + super(itemView); + nameTextView = itemView.findViewById(R.id.student_item__full_name); + avatarImageView = itemView.findViewById(R.id.student_item__avatar); + + itemView.setOnClickListener(v -> { + onStudentClickListener.onStudentClick((Student) v.getTag()); + notifyItemChanged(selectedStudent); + selectedStudent = getLayoutPosition(); + notifyItemChanged(selectedStudent); + }); + } + + private void bind(@NonNull Student student) { + String fullName = student.getSecondName() + " " + student.getFirstName(); + nameTextView.setText(fullName); + avatarImageView.setImageResource(student.getPhoto()); + } + } + + interface Listener { + void onStudentClick(Student student); + } +} diff --git a/app/src/main/res/anim/shake.xml b/app/src/main/res/anim/shake.xml new file mode 100644 index 0000000..628c6db --- /dev/null +++ b/app/src/main/res/anim/shake.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 304e72d..122af2b 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -3,7 +3,53 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto" tools:context=".MainActivity"> + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/student_item.xml b/app/src/main/res/layout/student_item.xml new file mode 100644 index 0000000..e69a3d8 --- /dev/null +++ b/app/src/main/res/layout/student_item.xml @@ -0,0 +1,35 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/student_list.xml b/app/src/main/res/layout/student_list.xml new file mode 100644 index 0000000..5beead4 --- /dev/null +++ b/app/src/main/res/layout/student_list.xml @@ -0,0 +1,46 @@ + + + + + + + +