release 0.1 #30
@ -4,6 +4,8 @@ apply plugin: 'kotlin-android'
|
|||||||
|
|
||||||
apply plugin: 'kotlin-android-extensions'
|
apply plugin: 'kotlin-android-extensions'
|
||||||
|
|
||||||
|
apply plugin: 'kotlin-kapt'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 29
|
compileSdkVersion 29
|
||||||
buildToolsVersion "29.0.2"
|
buildToolsVersion "29.0.2"
|
||||||
@ -21,19 +23,44 @@ android {
|
|||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
packagingOptions {
|
||||||
|
exclude 'META-INF/atomicfu.kotlin_module'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// retrofit
|
// standard
|
||||||
implementation "com.squareup.retrofit2:retrofit:2.6.2"
|
|
||||||
implementation "com.squareup.retrofit2:converter-gson:2.6.2"
|
|
||||||
|
|
||||||
implementation project(':wrapper')
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||||
implementation 'androidx.core:core-ktx:1.1.0'
|
implementation 'androidx.core:core-ktx:1.1.0'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||||
|
implementation 'com.google.android.material:material:1.0.0'
|
||||||
|
// wrapper
|
||||||
|
implementation project(':wrapper')
|
||||||
|
// retrofit
|
||||||
|
implementation "com.squareup.retrofit2:retrofit:2.6.2"
|
||||||
|
implementation "com.squareup.retrofit2:converter-gson:2.6.2"
|
||||||
|
// room database
|
||||||
|
implementation "androidx.room:room-runtime:$rootProject.roomVersion"
|
||||||
|
implementation "androidx.room:room-ktx:$rootProject.roomVersion"
|
||||||
|
kapt "androidx.room:room-compiler:$rootProject.roomVersion"
|
||||||
|
// lifecycle components
|
||||||
|
implementation "androidx.lifecycle:lifecycle-extensions:$rootProject.archLifecycleVersion"
|
||||||
|
//noinspection LifecycleAnnotationProcessorWithJava8
|
||||||
|
kapt "androidx.lifecycle:lifecycle-compiler:$rootProject.archLifecycleVersion"
|
||||||
|
// ViewModel Kotlin support
|
||||||
|
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$rootProject.archLifecycleVersion"
|
||||||
|
// Coroutines
|
||||||
|
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.coroutines"
|
||||||
|
// UI
|
||||||
|
implementation "com.google.android.material:material:$rootProject.materialVersion"
|
||||||
|
|
||||||
|
|
||||||
|
// TESTING
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.12'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
||||||
|
androidTestImplementation "androidx.room:room-testing:$rootProject.roomVersion"
|
||||||
|
androidTestImplementation "androidx.arch.core:core-testing:$rootProject.androidxArchVersion"
|
||||||
|
androidTestImplementation "androidx.arch.core:core-testing:$rootProject.coreTestingVersion"
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="it.unisannio.ding.ids.wedroid.app">
|
package="it.unisannio.ding.ids.wedroid.app">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
@ -9,6 +11,11 @@
|
|||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
|
<activity
|
||||||
|
android:name=".view.BoardsListsActivity"
|
||||||
|
android:label="@string/title_activity_boards_lists"
|
||||||
|
android:theme="@style/AppTheme.NoActionBar">
|
||||||
|
</activity>
|
||||||
<activity android:name=".MainActivity">
|
<activity android:name=".MainActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
@ -1,14 +1,21 @@
|
|||||||
package it.unisannio.ding.ids.wedroid.app
|
package it.unisannio.ding.ids.wedroid.app
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import it.unisannio.ding.ids.wedroid.wrapper.api.BoardService
|
import android.view.View
|
||||||
|
import it.unisannio.ding.ids.wedroid.app.view.BoardsListsActivity
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
val service : BoardService? = null
|
}
|
||||||
|
|
||||||
|
fun open(v: View) {
|
||||||
|
startActivity(
|
||||||
|
Intent(this, BoardsListsActivity::class.java)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
package it.unisannio.ding.ids.wedroid.app.data.dao
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.room.*
|
||||||
|
import it.unisannio.ding.ids.wedroid.app.data.entity.Board
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface BoardDao {
|
||||||
|
@Query("SELECT * from board_table ORDER BY title ASC")
|
||||||
|
fun getAllBoard(): LiveData<List<Board>>
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
suspend fun insert(board: Board)
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
suspend fun delete(board: Board)
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package it.unisannio.ding.ids.wedroid.app.data.database
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.room.Database
|
||||||
|
import androidx.room.Room
|
||||||
|
import androidx.room.RoomDatabase
|
||||||
|
import it.unisannio.ding.ids.wedroid.app.data.dao.BoardDao
|
||||||
|
import it.unisannio.ding.ids.wedroid.app.data.entity.Board
|
||||||
|
|
||||||
|
@Database(entities = [Board::class], version = 1, exportSchema = false)
|
||||||
|
abstract class BoardDatabase : RoomDatabase() {
|
||||||
|
|
||||||
|
abstract fun boardDao(): BoardDao
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@Volatile
|
||||||
|
private var INSTANCE: BoardDatabase? = null
|
||||||
|
|
||||||
|
fun getDatabase(context: Context): BoardDatabase {
|
||||||
|
val tempInstance = INSTANCE
|
||||||
|
if (tempInstance != null) {
|
||||||
|
return tempInstance
|
||||||
|
}
|
||||||
|
synchronized(this) {
|
||||||
|
val instance = Room.databaseBuilder(
|
||||||
|
context.applicationContext,
|
||||||
|
BoardDatabase::class.java,
|
||||||
|
"board_database"
|
||||||
|
).build()
|
||||||
|
INSTANCE = instance
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package it.unisannio.ding.ids.wedroid.app.data.entity
|
||||||
|
|
||||||
|
import androidx.room.ColumnInfo
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
|
||||||
|
@Entity(tableName = "board_table")
|
||||||
|
data class Board(
|
||||||
|
@PrimaryKey @ColumnInfo(name = "id") val id: String,
|
||||||
|
@ColumnInfo(name = "title") val title: String = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
fun it.unisannio.ding.ids.wedroid.wrapper.entity.Board.convert(): Board {
|
||||||
|
return Board(this.id, this.title)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,138 @@
|
|||||||
|
package it.unisannio.ding.ids.wedroid.app.data.repository
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import it.unisannio.ding.ids.wedroid.app.data.dao.BoardDao
|
||||||
|
import it.unisannio.ding.ids.wedroid.app.data.entity.Board
|
||||||
|
import it.unisannio.ding.ids.wedroid.app.data.entity.convert
|
||||||
|
import it.unisannio.ding.ids.wedroid.app.util.PreferenceReader
|
||||||
|
import it.unisannio.ding.ids.wedroid.wrapper.api.BoardService
|
||||||
|
import it.unisannio.ding.ids.wedroid.wrapper.entity.BoardBackgroundColor
|
||||||
|
import it.unisannio.ding.ids.wedroid.wrapper.entity.BoardPrototype
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import retrofit2.Call
|
||||||
|
import retrofit2.Callback
|
||||||
|
import retrofit2.Response
|
||||||
|
|
||||||
|
class BoardRepository(
|
||||||
|
private val dao: BoardDao,
|
||||||
|
private val service: BoardService,
|
||||||
|
private val reader: PreferenceReader
|
||||||
|
) {
|
||||||
|
val allBoards by lazy {
|
||||||
|
dao.getAllBoard()
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
synchronize()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun insertBoard(title: String) {
|
||||||
|
service.newBoard(
|
||||||
|
BoardPrototype.Builder()
|
||||||
|
.setOwner(reader.userId)
|
||||||
|
.setTitle(title)
|
||||||
|
.setBackgroundColor(BoardBackgroundColor.LIMEGREEN)
|
||||||
|
.build()
|
||||||
|
).enqueue(object : Callback<it.unisannio.ding.ids.wedroid.wrapper.entity.Board> {
|
||||||
|
override fun onFailure(
|
||||||
|
call: Call<it.unisannio.ding.ids.wedroid.wrapper.entity.Board>,
|
||||||
|
t: Throwable
|
||||||
|
) = logNetworkError(t.message)
|
||||||
|
|
||||||
|
override fun onResponse(
|
||||||
|
call: Call<it.unisannio.ding.ids.wedroid.wrapper.entity.Board>,
|
||||||
|
response: Response<it.unisannio.ding.ids.wedroid.wrapper.entity.Board>
|
||||||
|
) {
|
||||||
|
if (!response.isSuccessful) {
|
||||||
|
logNetworkError("${response.code()} ${response.message()}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val board = response.body()
|
||||||
|
|
||||||
|
if (board == null) {
|
||||||
|
logNetworkError("empty body")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
dao.insert(Board(board.id, title))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun synchronize() {
|
||||||
|
service.getBoardsFromUser(reader.userId)
|
||||||
|
.enqueue(object :
|
||||||
|
Callback<MutableList<it.unisannio.ding.ids.wedroid.wrapper.entity.Board>> {
|
||||||
|
|
||||||
|
override fun onFailure(
|
||||||
|
call: Call<MutableList<it.unisannio.ding.ids.wedroid.wrapper.entity.Board>>,
|
||||||
|
t: Throwable
|
||||||
|
) = logNetworkError(t.message)
|
||||||
|
|
||||||
|
override fun onResponse(
|
||||||
|
call: Call<MutableList<it.unisannio.ding.ids.wedroid.wrapper.entity.Board>>,
|
||||||
|
response: Response<MutableList<it.unisannio.ding.ids.wedroid.wrapper.entity.Board>>
|
||||||
|
) {
|
||||||
|
if (!response.isSuccessful) {
|
||||||
|
logNetworkError("${response.code()} ${response.message()}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// read boards from the body
|
||||||
|
val boards = (response.body() ?: return)
|
||||||
|
.map { it.convert() }
|
||||||
|
|
||||||
|
addNewBoardToDb(boards)
|
||||||
|
|
||||||
|
removeOldBoardsFromDb(boards)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteBoard(id: String) {
|
||||||
|
service.deleteBoard(id).enqueue(
|
||||||
|
object : Callback<Void> {
|
||||||
|
override fun onFailure(call: Call<Void>, t: Throwable) {
|
||||||
|
logNetworkError(t.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResponse(call: Call<Void>, response: Response<Void>) {
|
||||||
|
if (!response.isSuccessful) {
|
||||||
|
logNetworkError("${response.code()}, ${response.message()}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
dao.delete(Board(id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addNewBoardToDb(boards: Collection<Board>) {
|
||||||
|
boards.forEach {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
dao.insert(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun removeOldBoardsFromDb(boards: Collection<Board>) {
|
||||||
|
allBoards.value?.minus(boards)
|
||||||
|
?.forEach {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
dao.delete(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun logNetworkError(message: String?) {
|
||||||
|
Log.e("RETROFIT", message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
|||||||
|
package it.unisannio.ding.ids.wedroid.app.view
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import it.unisannio.ding.ids.wedroid.app.R
|
||||||
|
import it.unisannio.ding.ids.wedroid.app.view.adapter.BoardsListAdapter
|
||||||
|
import it.unisannio.ding.ids.wedroid.app.viewmodel.BoardListViewModel
|
||||||
|
|
||||||
|
import kotlinx.android.synthetic.main.activity_boards_lists.*
|
||||||
|
import kotlinx.android.synthetic.main.content_boards_lists.*
|
||||||
|
|
||||||
|
class BoardsListsActivity : AppCompatActivity() {
|
||||||
|
private lateinit var viewModel: BoardListViewModel
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_boards_lists)
|
||||||
|
setSupportActionBar(toolbar)
|
||||||
|
viewModel = ViewModelProvider(this).get(BoardListViewModel::class.java)
|
||||||
|
|
||||||
|
val adapter = BoardsListAdapter(this)
|
||||||
|
boardList.adapter = adapter
|
||||||
|
boardList.layoutManager = LinearLayoutManager(this)
|
||||||
|
|
||||||
|
viewModel.allBoards.observe(this, Observer {
|
||||||
|
it.let { adapter.setBoards(it) }
|
||||||
|
})
|
||||||
|
|
||||||
|
fab.setOnClickListener { view ->
|
||||||
|
viewModel.insertBoard("New board")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
|||||||
|
package it.unisannio.ding.ids.wedroid.app.view.adapter
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import it.unisannio.ding.ids.wedroid.app.R
|
||||||
|
import it.unisannio.ding.ids.wedroid.app.data.entity.Board
|
||||||
|
|
||||||
|
|
||||||
|
class BoardsListAdapter internal constructor(
|
||||||
|
context: Context
|
||||||
|
) : RecyclerView.Adapter<BoardsListAdapter.BoardViewHolder>() {
|
||||||
|
|
||||||
|
private val inflater = LayoutInflater.from(context)
|
||||||
|
private var boards = emptyList<Board>()
|
||||||
|
|
||||||
|
inner class BoardViewHolder(
|
||||||
|
view: View
|
||||||
|
) : RecyclerView.ViewHolder(view) {
|
||||||
|
val boardTitle: TextView = view.findViewById(R.id.boardTitle)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BoardViewHolder {
|
||||||
|
val view = inflater.inflate(R.layout.board_recycle_item, parent, false)
|
||||||
|
return BoardViewHolder(view)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int {
|
||||||
|
return boards.size
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: BoardViewHolder, position: Int) {
|
||||||
|
val board = boards[position]
|
||||||
|
holder.boardTitle.text = board.title
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun setBoards(boards: List<Board>) {
|
||||||
|
this.boards = boards
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package it.unisannio.ding.ids.wedroid.app.viewmodel
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import androidx.lifecycle.AndroidViewModel
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import it.unisannio.ding.ids.wedroid.app.util.ServicesFactory
|
||||||
|
import it.unisannio.ding.ids.wedroid.app.data.database.BoardDatabase
|
||||||
|
import it.unisannio.ding.ids.wedroid.app.data.entity.Board
|
||||||
|
import it.unisannio.ding.ids.wedroid.app.data.repository.BoardRepository
|
||||||
|
import it.unisannio.ding.ids.wedroid.app.util.DumReader
|
||||||
|
|
||||||
|
class BoardListViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
|
|
||||||
|
private val repository: BoardRepository = BoardRepository(
|
||||||
|
BoardDatabase.getDatabase(application).boardDao(),
|
||||||
|
ServicesFactory.boardService,
|
||||||
|
DumReader()
|
||||||
|
)
|
||||||
|
|
||||||
|
val allBoards: LiveData<List<Board>> = repository.allBoards
|
||||||
|
|
||||||
|
fun insertBoard(title: String) = repository.insertBoard(title)
|
||||||
|
|
||||||
|
fun deleteBoard(id: String) = repository.deleteBoard(id)
|
||||||
|
}
|
33
app/src/main/res/layout/activity_boards_lists.xml
Normal file
33
app/src/main/res/layout/activity_boards_lists.xml
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?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"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".view.BoardsListsActivity">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:theme="@style/AppTheme.AppBarOverlay">
|
||||||
|
|
||||||
|
<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/AppTheme.PopupOverlay" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<include layout="@layout/content_boards_lists" />
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/fab"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom|end"
|
||||||
|
android:layout_margin="@dimen/fab_margin"
|
||||||
|
app:srcCompat="@android:drawable/ic_dialog_email" />
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
@ -7,6 +7,7 @@
|
|||||||
tools:context=".MainActivity">
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/textView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Hello World!"
|
android:text="Hello World!"
|
||||||
@ -15,4 +16,15 @@
|
|||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:onClick="open"
|
||||||
|
android:text="Button"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/textView" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
12
app/src/main/res/layout/board_recycle_item.xml
Normal file
12
app/src/main/res/layout/board_recycle_item.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical" android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/boardTitle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="TextView" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
19
app/src/main/res/layout/content_boards_lists.xml
Normal file
19
app/src/main/res/layout/content_boards_lists.xml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout 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"
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||||
|
tools:context=".view.BoardsListsActivity"
|
||||||
|
tools:showIn="@layout/activity_boards_lists">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:id="@+id/boardList"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
3
app/src/main/res/values/dimens.xml
Normal file
3
app/src/main/res/values/dimens.xml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<resources>
|
||||||
|
<dimen name="fab_margin">16dp</dimen>
|
||||||
|
</resources>
|
@ -1,3 +1,5 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">wedroid</string>
|
<string name="app_name">wedroid</string>
|
||||||
|
<string name="title_activity_boards_list">BoardsListActivity</string>
|
||||||
|
<string name="title_activity_boards_lists">Boards</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -8,4 +8,13 @@
|
|||||||
<item name="colorAccent">@color/colorAccent</item>
|
<item name="colorAccent">@color/colorAccent</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="AppTheme.NoActionBar">
|
||||||
|
<item name="windowActionBar">false</item>
|
||||||
|
<item name="windowNoTitle">true</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
|
||||||
|
|
||||||
|
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -23,6 +23,15 @@ allprojects {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ext {
|
||||||
|
roomVersion = '2.2.2'
|
||||||
|
archLifecycleVersion = '2.2.0-rc02'
|
||||||
|
androidxArchVersion = '2.1.0'
|
||||||
|
coreTestingVersion = "2.1.0"
|
||||||
|
coroutines = '1.3.2'
|
||||||
|
materialVersion = "1.0.0"
|
||||||
|
}
|
||||||
|
|
||||||
task clean(type: Delete) {
|
task clean(type: Delete) {
|
||||||
delete rootProject.buildDir
|
delete rootProject.buildDir
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user