diff --git a/.idea/misc.xml b/.idea/misc.xml index bdd9278..704c883 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,7 +1,7 @@ - + diff --git a/app/build.gradle b/app/build.gradle index 0cc121a..b7302c0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,7 @@ plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' + id 'androidx.navigation.safeargs' } android { @@ -35,9 +36,19 @@ android { viewBinding true } } - dependencies { + def lifecycle_version = "2.6.1" + def arch_version = "2.2.0" + // ViewModel + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version" + // LiveData + implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version" + // reflection-free flavor + implementation 'com.github.kirich1409:viewbindingpropertydelegate-noreflection:1.5.8' + def nav_version = "2.5.3" + implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" + implementation "androidx.navigation:navigation-ui-ktx:$nav_version" implementation 'androidx.core:core-ktx:1.7.0' implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.google.android.material:material:1.8.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 05ea30b..29e1a9f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,10 +9,10 @@ android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" - android:theme="@style/Theme.Three_lines" + android:theme="@style/Theme.MaterialComponents.Light.NoActionBar" tools:targetApi="31"> diff --git a/app/src/main/java/com/example/three_lines/DataListAdapter.kt b/app/src/main/java/com/example/three_lines/DataListAdapter.kt deleted file mode 100644 index 8d7af79..0000000 --- a/app/src/main/java/com/example/three_lines/DataListAdapter.kt +++ /dev/null @@ -1,51 +0,0 @@ -package com.example.three_lines - -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.recyclerview.widget.DiffUtil -import androidx.recyclerview.widget.ListAdapter -import androidx.recyclerview.widget.RecyclerView -import com.example.three_lines.databinding.ActivityMainBinding -import com.example.three_lines.databinding.ViewContactBinding - -class DataListAdapter : ListAdapter(diffUtilCallback) { - - private var onClick : ( DataModel,String)-> Unit = {} - fun setCallback(callback :(DataModel) -> Unit){ - this.onClick = callback - } - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DataViewHolder { - val binding = ViewContactBinding.inflate(LayoutInflater.from(parent.context), parent, false) - return DataViewHolder(binding) - } - - override fun onBindViewHolder(holder: DataViewHolder, position: Int) { - holder.bind(getItem(position)) - } - - inner class DataViewHolder( - private val binding: ViewContactBinding, - ) : RecyclerView.ViewHolder(binding.root) { - fun bind(item: DataModel) { - with(binding) { - head.text = item.title - subhead.text = item.subtitle - root.setOnClickListener { - onClick.invoke(item) - } - } - - } - } -} - -val diffUtilCallback = object : DiffUtil.ItemCallback() { - - override fun areContentsTheSame(oldItem: DataModel, newItem: DataModel): Boolean { - return oldItem == newItem - } - - override fun areItemsTheSame(oldItem: DataModel, newItem: DataModel): Boolean { - return oldItem.id == newItem.id - } -} diff --git a/app/src/main/java/com/example/three_lines/DataModel.kt b/app/src/main/java/com/example/three_lines/DataModel.kt deleted file mode 100644 index 4eb6c7d..0000000 --- a/app/src/main/java/com/example/three_lines/DataModel.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.example.three_lines - -import java.util.UUID - -data class DataModel( - val title: String, - val subtitle: String, - val id : String = UUID.randomUUID().toString(), -) diff --git a/app/src/main/java/com/example/three_lines/MainActivity.kt b/app/src/main/java/com/example/three_lines/MainActivity.kt deleted file mode 100644 index 87aedc4..0000000 --- a/app/src/main/java/com/example/three_lines/MainActivity.kt +++ /dev/null @@ -1,58 +0,0 @@ -package com.example.three_lines - -import androidx.appcompat.app.AppCompatActivity -import android.os.Bundle -import android.widget.Toast -import com.example.three_lines.databinding.ActivityMainBinding - -class MainActivity : AppCompatActivity() { - private lateinit var binding: ActivityMainBinding - - private val listAdapter by lazy { - DataListAdapter() - } - - /* - private val dataList = listOf( - DataModel("rand1","subrand2"), - DataModel("rand3","subrand4"), - DataModel("rand5","subrand6"), - DataModel("rand7","subrand8"), - - ) - */ - private val dataList = mutableListOf().apply { - repeat(10) { - add(DataModel()) - } - - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - binding = ActivityMainBinding.inflate(layoutInflater) - setContentView(binding.root) - var size: Int = 0 - binding.recyclerView.adapter = listAdapter - binding.ButtonAdd.setOnClickListener { - dataList.add(DataModel()) - listAdapter.submitList(dataList.toList()) - //size++ - //listAdapter.submitList(dataList.take(size)) - - } - binding.ButtonRemove.setOnClickListener { - //if(size!=0) { - // size-- - // listAdapter.submitList(dataList.take(size)) - //} - dataList.removeLastOrNull() - listAdapter.submitList(dataList.toList()) - } - listAdapter.setCallback { model -> - Toast.makeText(this, model.title, Toast.LENGTH_LONG).show() - } - binding.recyclerView.adapter = listAdapter - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/example/three_lines/ViewContact.kt b/app/src/main/java/com/example/three_lines/ViewContact.kt deleted file mode 100644 index 1918979..0000000 --- a/app/src/main/java/com/example/three_lines/ViewContact.kt +++ /dev/null @@ -1,54 +0,0 @@ -package com.example.three_lines - -import android.content.Context -import android.util.AttributeSet -import android.view.LayoutInflater -import androidx.annotation.DrawableRes -import androidx.constraintlayout.widget.ConstraintLayout -import androidx.core.content.ContextCompat -import androidx.core.content.withStyledAttributes -import com.example.three_lines.databinding.ViewContactBinding - -class ViewContact @JvmOverloads constructor( - context: Context, - attributeSet: AttributeSet? = null, - defAttrsSet: Int = 0 -) : ConstraintLayout(context, attributeSet, defAttrsSet) { - private lateinit var binding: ViewContactBinding - - init { - binding = ViewContactBinding.inflate( - LayoutInflater.from(context), - this, - true - ) - context.withStyledAttributes( - attributeSet, - R.styleable.ViewContact, defAttrsSet, 0 - ) { - val title = getString(R.styleable.ViewContact_title)?.let { - title ->binding.head.text = title - } - val subtitle = getString(R.styleable.ViewContact_subtitle)?.let { - subtitle -> binding.subhead.text = subtitle - } - val image = getDrawable(R.styleable.ViewContact_image)?.let { - image -> binding.image.setImageDrawable(image) - } - } - } - - fun setTitle(text: String) { - binding.head.text = text - } - - fun setSubTitle(text: String) { - binding.subhead.text = text - } - - fun setImage(@DrawableRes imagesRes: Int) { - binding.image.setImageDrawable( - ContextCompat.getDrawable(context, imagesRes) - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/three_lines/data/Note.kt b/app/src/main/java/com/example/three_lines/data/Note.kt new file mode 100644 index 0000000..9253b3d --- /dev/null +++ b/app/src/main/java/com/example/three_lines/data/Note.kt @@ -0,0 +1,8 @@ +package com.example.three_lines.data + +import java.util.* + +data class Note( + val id : String = UUID.randomUUID().toString(), + val text : String, +) diff --git a/app/src/main/java/com/example/three_lines/data/NotesDataSource.kt b/app/src/main/java/com/example/three_lines/data/NotesDataSource.kt new file mode 100644 index 0000000..cd1f809 --- /dev/null +++ b/app/src/main/java/com/example/three_lines/data/NotesDataSource.kt @@ -0,0 +1,11 @@ +package com.example.three_lines.data + +object NotesDataSource { + val notesList = mutableListOf() + fun addNote(text : String){ + notesList.add(Note(text = text)) + } + fun deleteNote(note: Note){ + notesList.remove(note) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/three_lines/data/repository/NoteRepositoryImpl.kt b/app/src/main/java/com/example/three_lines/data/repository/NoteRepositoryImpl.kt new file mode 100644 index 0000000..0c9487d --- /dev/null +++ b/app/src/main/java/com/example/three_lines/data/repository/NoteRepositoryImpl.kt @@ -0,0 +1,20 @@ +package com.example.three_lines.data.repository + +import com.example.three_lines.data.Note +import com.example.three_lines.data.NotesDataSource + +class NoteRepositoryImpl( + private val notesDataSource : NotesDataSource = NotesDataSource +) : NotesRepository { + override fun getNotes(): List { + return notesDataSource.notesList + } + + override fun addNote(text: String) { + notesDataSource.addNote(text) + } + + override fun deleteNote(note: Note) { + notesDataSource.deleteNote(note) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/three_lines/data/repository/NotesRepository.kt b/app/src/main/java/com/example/three_lines/data/repository/NotesRepository.kt new file mode 100644 index 0000000..ffa8025 --- /dev/null +++ b/app/src/main/java/com/example/three_lines/data/repository/NotesRepository.kt @@ -0,0 +1,9 @@ +package com.example.three_lines.data.repository + +import com.example.three_lines.data.Note + +interface NotesRepository { + fun getNotes(): List + fun addNote(text: String) + fun deleteNote(note: Note) +} \ No newline at end of file diff --git a/app/src/main/java/com/example/three_lines/domain/AddNoteUseCase.kt b/app/src/main/java/com/example/three_lines/domain/AddNoteUseCase.kt new file mode 100644 index 0000000..80ccbbd --- /dev/null +++ b/app/src/main/java/com/example/three_lines/domain/AddNoteUseCase.kt @@ -0,0 +1,11 @@ +package com.example.three_lines.domain + +import com.example.three_lines.data.repository.NoteRepositoryImpl +import com.example.three_lines.data.repository.NotesRepository + +class AddNoteUseCase(private val notesRepository : NotesRepository = NoteRepositoryImpl() +) { + fun execute(text: String){ + notesRepository.addNote(text) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/three_lines/domain/DeleteNoteUseCase.kt b/app/src/main/java/com/example/three_lines/domain/DeleteNoteUseCase.kt new file mode 100644 index 0000000..4d176cf --- /dev/null +++ b/app/src/main/java/com/example/three_lines/domain/DeleteNoteUseCase.kt @@ -0,0 +1,12 @@ +package com.example.three_lines.domain + +import com.example.three_lines.data.Note +import com.example.three_lines.data.repository.NoteRepositoryImpl +import com.example.three_lines.data.repository.NotesRepository +class DeleteNoteUseCase( + private val notesRepository: NotesRepository = NoteRepositoryImpl() +) { + fun execute(note: Note) { + notesRepository.deleteNote(note) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/three_lines/domain/GetNotesUseCase.kt b/app/src/main/java/com/example/three_lines/domain/GetNotesUseCase.kt new file mode 100644 index 0000000..38e3d66 --- /dev/null +++ b/app/src/main/java/com/example/three_lines/domain/GetNotesUseCase.kt @@ -0,0 +1,13 @@ +package com.example.three_lines.domain + +import com.example.three_lines.data.Note +import com.example.three_lines.data.repository.NoteRepositoryImpl +import com.example.three_lines.data.repository.NotesRepository + +class GetNotesUseCase( + private val notesRepository: NotesRepository = NoteRepositoryImpl() +) { + fun execute(): List{ + return notesRepository.getNotes() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/three_lines/presentation/MainActivity.kt b/app/src/main/java/com/example/three_lines/presentation/MainActivity.kt new file mode 100644 index 0000000..faa3d71 --- /dev/null +++ b/app/src/main/java/com/example/three_lines/presentation/MainActivity.kt @@ -0,0 +1,18 @@ +package com.example.three_lines.presentation + +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import by.kirich1409.viewbindingdelegate.viewBinding +import com.example.three_lines.R +import com.example.three_lines.databinding.ActivityMainBinding + +class MainActivity : AppCompatActivity(R.layout.activity_main) { + private val binding by viewBinding(ActivityMainBinding::bind) + + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(binding.root) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/three_lines/presentation/fragment_add_note/AddNoteFragment.kt b/app/src/main/java/com/example/three_lines/presentation/fragment_add_note/AddNoteFragment.kt new file mode 100644 index 0000000..643f80b --- /dev/null +++ b/app/src/main/java/com/example/three_lines/presentation/fragment_add_note/AddNoteFragment.kt @@ -0,0 +1,31 @@ +package com.example.three_lines.presentation.fragment_add_note + +import android.os.Bundle +import android.view.View +import android.widget.Toast +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import androidx.navigation.fragment.findNavController +import by.kirich1409.viewbindingdelegate.viewBinding +import com.example.three_lines.R +import com.example.three_lines.databinding.FragmentAddNoteBinding +import com.example.three_lines.presentation.list.NotesListViewModel + +class AddNoteFragment : Fragment(R.layout.fragment_add_note) { + private val viewModel by viewModels() + private val binding by viewBinding(FragmentAddNoteBinding::bind) + + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + with(binding) { + toolbar.setNavigationOnClickListener { + findNavController().popBackStack() + } + floatingActionButton.setOnClickListener { + viewModel.onAddClicked(editTextNote.text.toString()) + findNavController().popBackStack() + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/three_lines/presentation/list/NoteListAdapter.kt b/app/src/main/java/com/example/three_lines/presentation/list/NoteListAdapter.kt new file mode 100644 index 0000000..be9ad7c --- /dev/null +++ b/app/src/main/java/com/example/three_lines/presentation/list/NoteListAdapter.kt @@ -0,0 +1,50 @@ +package com.example.three_lines.presentation.list + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.example.three_lines.data.Note +import com.example.three_lines.databinding.ItemNoteBinding + +class NoteListAdapter : ListAdapter(diffUtil) { + private var onNoteClick : (Note) -> Unit = {} + fun setCallBack(callback: (Note)->Unit){ + this.onNoteClick = callback + } + private var onNoteLongClick: (Note) -> Unit = {} + + fun setLongCallBack(callback: (Note) -> Unit) { + this.onNoteLongClick = callback + } + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NoteViewHolder { + val binding = ItemNoteBinding.inflate(LayoutInflater.from(parent.context), parent, false) + return NoteViewHolder(binding) + } + + override fun onBindViewHolder(holder: NoteViewHolder, position: Int) { + holder.bind(getItem(position)) + } + + inner class NoteViewHolder( + private var binding: ItemNoteBinding + ) : RecyclerView.ViewHolder(binding.root) { + fun bind(item: Note) { + with(binding){ + root.setOnClickListener { onNoteClick(item) } + textViewText.text = item.text + root.setOnLongClickListener { + onNoteLongClick(item) + true + } + } + } + } +} +val diffUtil = object : DiffUtil.ItemCallback() { + + override fun areContentsTheSame(oldItem: Note, newItem: Note) = oldItem==newItem + + override fun areItemsTheSame(oldItem: Note, newItem: Note)= oldItem.id == newItem.id +} diff --git a/app/src/main/java/com/example/three_lines/presentation/list/NoteListFragment.kt b/app/src/main/java/com/example/three_lines/presentation/list/NoteListFragment.kt new file mode 100644 index 0000000..02d5018 --- /dev/null +++ b/app/src/main/java/com/example/three_lines/presentation/list/NoteListFragment.kt @@ -0,0 +1,50 @@ +package com.example.three_lines.presentation.list + +import android.os.Bundle +import android.view.View +import android.widget.Toast +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import androidx.navigation.fragment.findNavController +import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.StaggeredGridLayoutManager +import by.kirich1409.viewbindingdelegate.viewBinding +import com.example.three_lines.R +import com.example.three_lines.databinding.FragmentNoteListBinding + +class NoteListFragment : Fragment(R.layout.fragment_note_list) { + + + private val binding by viewBinding(FragmentNoteListBinding::bind) + private val viewModel by viewModels() + private val listAdapter = NoteListAdapter() + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + viewModel.getNotes() + with(binding) { + recyclerview.apply { + + + layoutManager = StaggeredGridLayoutManager(2, RecyclerView.VERTICAL) + adapter = listAdapter.apply { + setLongCallBack { note -> + Toast.makeText( + requireContext(), + "Запись : \"" + note.text + "\" удалена", + Toast.LENGTH_SHORT + ).show() + viewModel.onDeleteClicked(note) + } + } + } + floatingActionButton.setOnClickListener { + findNavController().navigate( + NoteListFragmentDirections.actionNoteListFragmentToAddNoteFragment() + ) + } + viewModel.notesListLiveData.observe(viewLifecycleOwner) { + listAdapter.submitList(it) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/three_lines/presentation/list/NotesListViewModel.kt b/app/src/main/java/com/example/three_lines/presentation/list/NotesListViewModel.kt new file mode 100644 index 0000000..8492994 --- /dev/null +++ b/app/src/main/java/com/example/three_lines/presentation/list/NotesListViewModel.kt @@ -0,0 +1,33 @@ +package com.example.three_lines.presentation.list + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.example.three_lines.data.Note +import com.example.three_lines.domain.AddNoteUseCase +import com.example.three_lines.domain.DeleteNoteUseCase +import com.example.three_lines.domain.GetNotesUseCase +import kotlinx.coroutines.launch + +class NotesListViewModel( + private val getNotesUseCase: GetNotesUseCase = GetNotesUseCase(), + private val addNoteUseCase: AddNoteUseCase = AddNoteUseCase(), + private val deleteNoteUseCase: DeleteNoteUseCase = DeleteNoteUseCase(), +): ViewModel() { + + private val _notesListLiveData = MutableLiveData>() + val notesListLiveData : LiveData> = _notesListLiveData + fun onAddClicked(text: String){ + addNoteUseCase.execute(text) + getNotes() + } + fun getNotes(){ + _notesListLiveData.value = getNotesUseCase.execute().toList() + } + + fun onDeleteClicked(note: Note) { + deleteNoteUseCase.execute(note) + getNotes() + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_image.xml b/app/src/main/res/drawable/ic_add_image.xml new file mode 100644 index 0000000..1ca4425 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_image.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_add_quick_note.xml b/app/src/main/res/drawable/ic_add_quick_note.xml new file mode 100644 index 0000000..853093e --- /dev/null +++ b/app/src/main/res/drawable/ic_add_quick_note.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_back_24.xml b/app/src/main/res/drawable/ic_back_24.xml new file mode 100644 index 0000000..8452791 --- /dev/null +++ b/app/src/main/res/drawable/ic_back_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_send.xml b/app/src/main/res/drawable/ic_send.xml new file mode 100644 index 0000000..906314c --- /dev/null +++ b/app/src/main/res/drawable/ic_send.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index c01fb49..48ce58f 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,37 +1,17 @@ - - - - - - -