Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.trainingdeveloperpro.giang

import android.app.Activity
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.text.TextUtils
import android.widget.Button
import android.widget.EditText
import kotlinx.android.synthetic.main.activity_add_new_student.*

class AddNewStudent : AppCompatActivity() {
private lateinit var name: EditText
private lateinit var age: EditText
private lateinit var phone: EditText

public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_add_new_student)
supportActionBar!!.hide()

name = findViewById(R.id.edtName)
age = findViewById(R.id.edtAge)
phone = findViewById(R.id.edtPhone)

val button = findViewById<Button>(R.id.btnAddAStudent)
button.setOnClickListener {
val replyIntent = Intent()

if (TextUtils.isEmpty(name.text) ||
TextUtils.isEmpty(age.text) ||
TextUtils.isEmpty(phone.text)
) {
setResult(Activity.RESULT_CANCELED, replyIntent)
}
else {
val name = edtName.text.toString()
val age = edtAge.text.toString()
val phone = edtPhone.text.toString()

replyIntent.putExtra(EXTRA_AGE, age)
replyIntent.putExtra(EXTRA_PHONE, phone)
replyIntent.putExtra(EXTRA_NAME, name)

setResult(Activity.RESULT_OK, replyIntent)
}
finish()
}
}

companion object {
const val EXTRA_NAME = "com.example.android.studentlistsql.EXTRA_NAME"
const val EXTRA_AGE = "com.example.android.studentlistsql.EXTRA_AGE"
const val EXTRA_PHONE = "com.example.android.studentlistsql.EXTRA_PHONE"

}
}
12 changes: 12 additions & 0 deletions giang/src/main/java/com.trainingdeveloperpro.giang/LogTool.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.trainingdeveloperpro.giang

import android.util.Log

class LogTool {
companion object {
fun logD(tag: String, message: String) {
if (BuildConfig.DEBUG)
Log.d(tag, message)
}
}
}
13 changes: 13 additions & 0 deletions giang/src/main/java/com.trainingdeveloperpro.giang/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.trainingdeveloperpro.giang

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportActionBar!!.hide()
}
}
24 changes: 24 additions & 0 deletions giang/src/main/java/com.trainingdeveloperpro.giang/MyDiffUtil.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.trainingdeveloperpro.giang

import androidx.recyclerview.widget.DiffUtil


class MyDiffUtil(internal var newList: StudentViewModel?, internal var oldList: StudentViewModel?) :
DiffUtil.Callback() {

override fun getOldListSize(): Int {
return if (oldList != null) oldList!!.size() else 0
}

override fun getNewListSize(): Int {
return if (newList != null) newList!!.size() else 0
}

override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return newList!!.getName(newItemPosition) === oldList!!.getName(newItemPosition)
}

override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return false
}
}
10 changes: 10 additions & 0 deletions giang/src/main/java/com.trainingdeveloperpro.giang/Student.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.trainingdeveloperpro.giang

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey

@Entity(tableName = "student_table")
data class Student(@PrimaryKey @ColumnInfo(name = "name") val name: String ,
@ColumnInfo(name = "phone") val phone: String,
@ColumnInfo(name = "age") val age: Int)
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.trainingdeveloperpro.giang

import android.content.Context
import androidx.recyclerview.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import java.util.*


class StudentAdapter internal constructor(
context: Context
) : RecyclerView.Adapter<StudentAdapter.StudentViewHolder>() {

private val inflater: LayoutInflater = LayoutInflater.from(context)
private var students = Collections.emptyList<Student>() // Cached copy of words

inner class StudentViewHolder(private val itemview: View) : RecyclerView.ViewHolder(itemview) {
var name: TextView
var phone: TextView
var age: TextView


init {
name = itemview.findViewById(R.id.txtName)
age = itemview.findViewById(R.id.txtAge)
phone = itemview.findViewById(R.id.txtPhone)
itemview.setOnClickListener { deleteStudent(adapterPosition) }
}

fun deleteStudent(position: Int) {
students.removeAt(position)
notifyItemRemoved(position)
}
}


override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): StudentViewHolder {
val itemView = inflater.inflate(R.layout.item_student, parent, false)
return StudentViewHolder(itemView)
}

override fun onBindViewHolder(holder: StudentViewHolder, position: Int) {
val current = students[position]
holder.name.text = current.name
holder.age.text = current.age.toString()
holder.phone.text = current.phone
}

internal fun setStudent(students: List<Student>) {
this.students = students
notifyDataSetChanged()
}

override fun getItemCount() = students.size
}


21 changes: 21 additions & 0 deletions giang/src/main/java/com.trainingdeveloperpro.giang/StudentDao.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.trainingdeveloperpro.giang

import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query


@Dao
interface StudentDao {

@Query("SELECT * from student_table ORDER BY name ASC")
fun getAlphabetizedWords(): LiveData<List<Student>>

@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(student: Student)

@Query("DELETE FROM student_table")
suspend fun deleteAll()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package com.trainingdeveloperpro.giang

import android.app.Activity
import android.app.Activity.RESULT_OK
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import androidx.fragment.app.Fragment
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.*
import com.trainingdeveloperpro.giang.AddNewStudent.Companion.EXTRA_AGE
import com.trainingdeveloperpro.giang.AddNewStudent.Companion.EXTRA_NAME
import com.trainingdeveloperpro.giang.AddNewStudent.Companion.EXTRA_PHONE
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.trainingdeveloperpro.giang.StudentViewModel as studentViewModel

val newStudentctivityRequestCode = 1

class StudentFragment : Fragment() {
private lateinit var studentViewModel: studentViewModel
private lateinit var recyclerView : RecyclerView
lateinit var adapter: StudentAdapter

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

val rootView = inflater.inflate(R.layout.fragment_student, container, false)

recyclerView = rootView.findViewById<RecyclerView>(R.id.listStdudent)
adapter = StudentAdapter(activity!!.applicationContext)
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(activity)

studentViewModel = ViewModelProviders.of(this).get(com.trainingdeveloperpro.giang.StudentViewModel::class.java)

studentViewModel.allStudents.observe(this, Observer { words ->
words?.let { adapter.setStudent(it) }
})

val btnAdd = rootView.findViewById<FloatingActionButton>(R.id.btnAdd)
btnAdd.setOnClickListener {
val intent = Intent(activity, AddNewStudent::class.java)
startActivityForResult(intent, newStudentctivityRequestCode)
}

setGridLayout()

setLines()

return rootView
}

private fun setLines() {
val vertical = DividerItemDecoration(activity!!, DividerItemDecoration.VERTICAL)
recyclerView.addItemDecoration(vertical)
}

private fun setGridLayout() {
val gridLayoutManager = GridLayoutManager(activity, 2)
gridLayoutManager.orientation = GridLayoutManager.VERTICAL
recyclerView.setLayoutManager(gridLayoutManager)
}

override fun onActivityResult(requestCode: Int, resultCode: Int, intentData: Intent?) {

if (requestCode == newStudentctivityRequestCode && resultCode == RESULT_OK) {
intentData?.let { data ->
val student = Student(
data.getStringExtra(EXTRA_NAME),
data.getStringExtra(EXTRA_PHONE),
data.getStringExtra(EXTRA_AGE).toInt()
)

var newListStudent: com.trainingdeveloperpro.giang.StudentViewModel = studentViewModel
newListStudent.insert(student)
var diffUtil: MyDiffUtil = MyDiffUtil(newListStudent,studentViewModel)
val diffResult = DiffUtil.calculateDiff(diffUtil)

studentViewModel = newListStudent
diffResult.dispatchUpdatesTo(adapter)
}
} else {
Toast.makeText(
activity,
R.string.toastAddNoone,
Toast.LENGTH_LONG
).show()
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.trainingdeveloperpro.giang

import androidx.lifecycle.LiveData


class StudentRepository(private val studentDao: StudentDao) {
val allStudents: LiveData<List<Student>> = studentDao.getAlphabetizedWords()

suspend fun insert(student: Student) {
studentDao.insert(student)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.trainingdeveloperpro.giang

import androidx.sqlite.db.SupportSQLiteDatabase
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import android.content.Context
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

@Database(entities = [Student::class], version = 1)
abstract class StudentRoomDatabase : RoomDatabase() {

abstract fun studentDao(): StudentDao

companion object {
@Volatile
private var INSTANCE: StudentRoomDatabase? = null

fun getDatabase(
context: Context,
scope: CoroutineScope
): StudentRoomDatabase {
// if the INSTANCE is not null, then return it,
// if it is, then create the database
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
StudentRoomDatabase::class.java,
"student_database"
)
// Wipes and rebuilds instead of migrating if no Migration object.
// Migration is not part of this codelab.
.fallbackToDestructiveMigration()
.addCallback(StudentDatabaseCallback(scope))
.build()
INSTANCE = instance
// return instance
instance
}
}

private class StudentDatabaseCallback(
private val scope: CoroutineScope
) : RoomDatabase.Callback() {
override fun onOpen(db: SupportSQLiteDatabase) {
super.onOpen(db)
// If you want to keep the data through app restarts,
// comment out the following line.
INSTANCE?.let { database ->
scope.launch {
populateDatabase(database.studentDao())
}
}
}
}

suspend fun populateDatabase(studentDao: StudentDao) {
studentDao.deleteAll()
studentDao.insert(Student("Giang", "03214212381", 20))
studentDao.insert(Student("Nam", "03214212322", 21))
studentDao.insert(Student("Ha", "0321421322", 11))
studentDao.insert(Student("Kha", "03214212332", 32))
studentDao.insert(Student("Hao", "03214212441", 12))
studentDao.insert(Student("Hoc", "03214212332", 21))
for (i in 1..20) {
studentDao.insert(Student("Name $i", "0321421233$i", 13 + i))
}
}
}

}
Loading