feat: Basic list

parent 574323bb
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
...@@ -9,11 +9,11 @@ android { ...@@ -9,11 +9,11 @@ android {
buildToolsVersion "29.0.2" buildToolsVersion "29.0.2"
defaultConfig { defaultConfig {
applicationId "fr.plnech.dunbar" applicationId "fr.plnech.dunbar"
minSdkVersion 15 minSdkVersion 21
targetSdkVersion 28 targetSdkVersion 28
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
buildTypes { buildTypes {
release { release {
...@@ -26,10 +26,10 @@ android { ...@@ -26,10 +26,10 @@ android {
dependencies { dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar']) implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3' implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.android.support:design:28.0.0' implementation 'com.google.android.material:material:1.0.0'
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
} }
package fr.plnech.dunbar package fr.plnech.dunbar
import android.support.test.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import android.support.test.runner.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
......
...@@ -2,8 +2,12 @@ ...@@ -2,8 +2,12 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="fr.plnech.dunbar"> package="fr.plnech.dunbar">
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.READ_SMS" />
<application <application
android:allowBackup="true" android:allowBackup="false"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
...@@ -20,5 +24,4 @@ ...@@ -20,5 +24,4 @@
</intent-filter> </intent-filter>
</activity> </activity>
</application> </application>
</manifest> </manifest>
\ No newline at end of file
package fr.plnech.dunbar
fun String.plural(count: Int = 1): String {
return when {
count > 1 -> this + "s"
else -> this
}
}
\ No newline at end of file
package fr.plnech.dunbar package fr.plnech.dunbar
// * @see [contacts doc](https://developer.android.com/training/contacts-provider/retrieve-names)
class Friends { class Friends {
fun loadFriends() {
}
} }
\ No newline at end of file
package fr.plnech.dunbar package fr.plnech.dunbar
import android.os.Bundle import android.os.Bundle
import android.support.design.widget.Snackbar import android.provider.ContactsContract
import android.support.v7.app.AppCompatActivity
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.widget.ArrayAdapter
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.content_main.*
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
private val CONTENT_VIEW_ID = 10101010
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)
setSupportActionBar(toolbar) setSupportActionBar(toolbar)
fab.setOnClickListener { view -> fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show() .setAction("Action", null).show()
} }
fetchFriends()
} }
override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun onCreateOptionsMenu(menu: Menu): Boolean {
...@@ -36,4 +47,40 @@ class MainActivity : AppCompatActivity() { ...@@ -36,4 +47,40 @@ class MainActivity : AppCompatActivity() {
else -> super.onOptionsItemSelected(item) else -> super.onOptionsItemSelected(item)
} }
} }
fun fetchFriends() {
contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
null,
null,
null
)?.let {
val contacts = mutableListOf<List<Pair<String, String>>>()
while (it.moveToNext()) {
contacts.add(mutableListOf<Pair<String, String>>().also { contact ->
it.columnNames.forEach { name ->
contact.add(Pair(name, it.getString(it.getColumnIndex(name))))
}
})
}
friends.adapter =
ArrayAdapter<String>(this, R.layout.contact, R.id.name,
contacts.map { contact ->
contact.filter { !it.second.isNullOrBlank() }
.joinToString { "${it.first}:${it.second}" }
})
val nbFriends = friends.adapter.count
welcomeTitle.text = "$nbFriends ${"friend".plural(nbFriends)} on Dunbar"
Toast.makeText(this@MainActivity, "$nbFriends ", Toast.LENGTH_LONG).show()
it?.close()
}
}
} }
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".MainActivity"> tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay"> android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary" android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" /> app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_main" /> <include layout="@layout/content_main" />
<android.support.design.widget.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab" android:id="@+id/fab"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
...@@ -30,4 +30,4 @@ ...@@ -30,4 +30,4 @@
android:layout_margin="@dimen/fab_margin" android:layout_margin="@dimen/fab_margin"
app:srcCompat="@android:drawable/ic_dialog_email" /> app:srcCompat="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file \ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView 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:elevation="5dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/pic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:height="150dp"
android:src="@android:drawable/"
android:elevation="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/name"
app:layout_constraintTop_toTopOf="parent"
tools:src="@tools:sample/avatars"
android:contentDescription="TODO" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:clickable="true"
android:focusable="true"
android:maxLines="2"
android:textAppearance="@style/TextAppearance.AppCompat.Title"
android:textSize="32sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@id/pic"
app:layout_constraintRight_toLeftOf="@id/name"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/full_names" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/contact_list_item"
tools:listitem="@layout/contact"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
...@@ -9,12 +9,27 @@ ...@@ -9,12 +9,27 @@
tools:showIn="@layout/activity_main"> tools:showIn="@layout/activity_main">
<TextView <TextView
android:id="@+id/welcomeTitle"
android:layout_marginTop="50dp"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Hello World!" tools:text="N friends on Dunbar"
app:layout_constraintBottom_toBottomOf="parent" android:textSize="24sp"
app:layout_constraintBottom_toTopOf="@id/friends"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout> <ListView
\ No newline at end of file android:id="@+id/friends"
android:layout_width="match_parent"
android:padding="10dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/welcomeTitle"
tools:listitem="@layout/contact"
tools:text="@tools:sample/last_names" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
...@@ -8,7 +8,7 @@ buildscript { ...@@ -8,7 +8,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.5.0' classpath 'com.android.tools.build:gradle:3.5.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files
......
...@@ -13,3 +13,5 @@ org.gradle.jvmargs=-Xmx1536m ...@@ -13,3 +13,5 @@ org.gradle.jvmargs=-Xmx1536m
# org.gradle.parallel=true # org.gradle.parallel=true
# Kotlin code style for this project: "official" or "obsolete": # Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official kotlin.code.style=official
android.useAndroidX=true
android.enableJetifier=true
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment