New commit with added features:

- filter list
 - new list item layout
This commit is contained in:
2019-12-03 23:19:27 +11:00
parent 40d712c25f
commit f917dabe3f
13 changed files with 261 additions and 33 deletions

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -8,7 +8,7 @@ android {
compileSdkVersion 28 compileSdkVersion 28
defaultConfig { defaultConfig {
applicationId "com.example.h_mal.myapplication" applicationId "com.example.h_mal.myapplication"
minSdkVersion 15 minSdkVersion 23
targetSdkVersion 28 targetSdkVersion 28
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
@@ -33,4 +33,5 @@ dependencies {
implementation 'com.squareup.okhttp3:okhttp:4.2.1' implementation 'com.squareup.okhttp3:okhttp:4.2.1'
implementation 'com.google.code.gson:gson:2.8.5' implementation 'com.google.code.gson:gson:2.8.5'
androidTestImplementation 'com.android.support.test:rules:1.0.2' androidTestImplementation 'com.android.support.test:rules:1.0.2'
implementation 'com.android.support:cardview-v7:28.0.0'
} }

View File

@@ -1,28 +1,86 @@
package com.example.h_mal.myapplication package com.example.h_mal.myapplication
import android.content.Context import android.content.Context
import android.content.Intent
import android.net.Uri
import android.net.UrlQuerySanitizer
import android.opengl.Visibility
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import android.widget.Filter
import com.example.h_mal.myapplication.model.JsonObject import com.example.h_mal.myapplication.model.JsonObject
import kotlinx.android.synthetic.main.repo_list_item.view.* import kotlinx.android.synthetic.main.repo_list_item.view.*
//custom list adapter extends from array adater
class ListViewAdapter(context: Context, objects: MutableList<JsonObject>) : class ListViewAdapter(context: Context, objects: MutableList<JsonObject>) :
ArrayAdapter<JsonObject>(context, 0, objects){ ArrayAdapter<JsonObject>(context, 0, objects){
//populate each view
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
//if the current view is null then inflate our list item object into list
var view: View? = convertView var view: View? = convertView
if (view == null) { if (view == null) {
view = LayoutInflater.from(context).inflate(R.layout.repo_list_item, parent, false) view = LayoutInflater.from(context).inflate(R.layout.repo_list_item, parent, false)!!
} }
//get the current item from the current position
val item = getItem(position) val item = getItem(position)
view?.name?.text = item?.name //set name and description
view?.description?.text = item?.description view.name?.text = item?.name
view.description?.text = item?.description
//parse date from the date time string and set the date
val dateString = item?.date?.split('T')?.get(0)
view.date?.text = dateString
return view!! //check if the language object is null
if (item.language != null){
//language exists in object
//view holdin the language to be visible
view.lang_layout.visibility = View.VISIBLE
//language text and corresponding colour according to github is applied
view.lang?.text = item.language
getColor(item.language)?.let { it1 -> view.lang_col.setCardBackgroundColor(it1) }
}else{
//language was null therefore view to be hidden
view.lang_layout.visibility = View.GONE
}
//apply on click listener to item
view.setOnClickListener{
//click item opens then url
openLink(item.repoUrlString)
}
return view
}
//function for opening the link
fun openLink(urlString : String?){
//open link to repo if the url is not nu;;
if (urlString != null){
val openURL = Intent(Intent.ACTION_VIEW)
openURL.data = Uri.parse(urlString)
context.startActivity(openURL)
}
}
//get the corresponding colour based on the programming language
fun getColor(language: String?) : Int?{
return when(language) {
"Ruby" -> context.getColor(R.color.Ruby)
"Java"-> context.getColor(R.color.Java)
"Objective-C" -> context.getColor(R.color.ObjectiveC)
"JavaScript" -> context.getColor(R.color.JavaScript)
"CSS" -> context.getColor(R.color.CSS)
"Shell" -> context.getColor(R.color.Shell)
//if the language has no match return nothing
else -> null
}
} }
} }

View File

@@ -4,6 +4,10 @@ import android.content.Context
import android.support.v7.app.AppCompatActivity import android.support.v7.app.AppCompatActivity
import android.os.Bundle import android.os.Bundle
import android.support.v4.widget.SwipeRefreshLayout import android.support.v4.widget.SwipeRefreshLayout
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.widget.SearchView
import com.example.h_mal.myapplication.model.JsonObject import com.example.h_mal.myapplication.model.JsonObject
import com.google.gson.Gson import com.google.gson.Gson
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
@@ -12,49 +16,101 @@ import java.io.IOException
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
lateinit var thecontext: Context lateinit var searchView: SearchView
val urlString = "https://api.github.com/orgs/square/repos"
companion object{
val urlString = "https://api.github.com/orgs/square/repos"
}
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)
thecontext = this //begin populating list
executeTask() executeTask()
//set a listener for the swipe to refresh
swipe_refresh.setOnRefreshListener(swipeRefreshListener) swipe_refresh.setOnRefreshListener(swipeRefreshListener)
} }
//implement search interface in the menu
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
//inflate custom menu as our menu
menuInflater.inflate(R.menu.menu, menu)
//extract searchview
val searchItem = menu?.findItem(R.id.search)
//set searchview globally
searchView = searchItem?.actionView as SearchView
return true
}
val swipeRefreshListener = SwipeRefreshLayout.OnRefreshListener{ val swipeRefreshListener = SwipeRefreshLayout.OnRefreshListener{
//populate list when pulling to refresh
executeTask() executeTask()
} }
fun executeTask(){ fun executeTask(){
//clear list before populating
list_view.adapter = null
//create url from url string urlstring
val url = Request.Builder().url(urlString).build() val url = Request.Builder().url(urlString).build()
//create a okhttpclient for a get request from url
val client = OkHttpClient() val client = OkHttpClient()
//call the url and retrieve its callback
client.newCall(url).enqueue(object: Callback { client.newCall(url).enqueue(object: Callback {
//failure of retrieval callback
override fun onFailure(call: Call, e: IOException) { override fun onFailure(call: Call, e: IOException) {
//print error to log
System.err.println(e) System.err.println(e)
//if swipe refresh is refreshing then stop
swipe_refresh.isRefreshing = false swipe_refresh.isRefreshing = false
//list is empty
} }
//successful retrieval callback
override fun onResponse(call: Call, response: Response) { override fun onResponse(call: Call, response: Response) {
//get the JSON from the body
val urlResponse = response.body?.string() val urlResponse = response.body?.string()
//print the response to the logs
println("response = $urlResponse") println("response = $urlResponse")
//create gson object
val gson = Gson() val gson = Gson()
//create a mutable list of objects extracted from the json text
val objectList = gson.fromJson(urlResponse, Array<JsonObject>::class.java).asList().toMutableList() val objectList = gson.fromJson(urlResponse, Array<JsonObject>::class.java).asList().toMutableList()
runOnUiThread{ if (objectList.size >0){
list_view.adapter = ListViewAdapter(thecontext, objectList) //update the ui
swipe_refresh.isRefreshing = false runOnUiThread{
//custom list view adapter created
val adapterLV = ListViewAdapter(baseContext, objectList)
//apply adapter to listview
list_view.adapter = adapterLV
//if swipe refresh is refreshing then stop
swipe_refresh.isRefreshing = false
//search view has its query change listener applied
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener{
override fun onQueryTextSubmit(query: String?): Boolean {
return true
}
//as the test is changed the list is filtered
override fun onQueryTextChange(newText: String?): Boolean {
//filter list function
adapterLV.filter.filter(newText)
return true
}
})
}
}else{
//list is empty
} }
} }

View File

@@ -9,6 +9,8 @@ data class JsonObject(
var description : String? = null, var description : String? = null,
@SerializedName("language") @SerializedName("language")
var language : String? = null, var language : String? = null,
@SerializedName("created_at")
var date : String? = null,
@SerializedName("html_url") @SerializedName("html_url")
var repoUrlString : String? = null var repoUrlString : String? = null
) )

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
</vector>

View File

@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
</vector>

View File

@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M3,18h6v-2L3,16v2zM3,6v2h18L21,6L3,6zM3,13h12v-2L3,11v2z"/>
</vector>

View File

@@ -19,4 +19,6 @@
</android.support.v4.widget.SwipeRefreshLayout> </android.support.v4.widget.SwipeRefreshLayout>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"/>
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>

View File

@@ -1,18 +1,83 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"> android:layout_width="match_parent"
<TextView android:layout_height="wrap_content"
android:hint="name" xmlns:tools="http://schemas.android.com/tools">
android:layout_margin="12dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" tools:layout_editor_absoluteY="16dp" <android.support.v7.widget.CardView
tools:layout_editor_absoluteX="16dp" android:id="@+id/name"/> android:layout_width="match_parent"
<TextView android:layout_height="wrap_content"
android:hint="description"
android:layout_marginLeft="12dp" android:layout_marginLeft="12dp"
android:layout_below="@id/name" android:layout_marginTop="6dp"
android:layout_width="wrap_content" android:layout_marginRight="12dp"
android:layout_height="wrap_content" tools:layout_editor_absoluteY="44dp" android:layout_marginBottom="6dp"
tools:layout_editor_absoluteX="16dp" android:id="@+id/description"/> app:cardCornerRadius="12dp">
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:textSize="22sp"
android:textStyle="bold"
android:textColor="#30ABC5"
tools:text="Name of repo" />
<TextView
android:id="@+id/date"
android:layout_width="0dp"
android:layout_height="match_parent"
android:gravity="center"
android:layout_weight="1"
tools:text="19/04/2018" />
</LinearLayout>
<View android:layout_width="match_parent"
android:layout_height="1dp"
android:backgroundTint="#30ABC5"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"/>
<TextView
android:id="@+id/description"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="2dp"
android:gravity="center_vertical"
android:textSize="18sp"
tools:text="Multi line description, text and more text then text
add more text more of a description. Multi line
description, text and more text then text add
more text more of a description." />
<LinearLayout android:id="@+id/lang_layout" android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_marginTop="6dp" android:gravity="right">
<TextView android:layout_width="wrap_content" android:layout_height="match_parent"
tools:text="Java" android:gravity="center" android:id="@+id/lang"/>
<android.support.v7.widget.CardView
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginLeft="4dp"
app:cardCornerRadius="8dp" app:cardBackgroundColor="#E03F3F" android:id="@+id/lang_col"/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</FrameLayout>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/search"
android:title="@string/search_title"
android:icon="@drawable/ic_search_white_24dp"
app:showAsAction="collapseActionView|ifRoom" app:actionViewClass="android.widget.SearchView"/>
</menu>

View File

@@ -1,6 +1,15 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<color name="colorPrimary">#008577</color> <color name="colorPrimary">#30ABC5</color>
<color name="colorPrimaryDark">#00574B</color> <color name="colorPrimaryDark">#247E91</color>
<color name="colorAccent">#D81B60</color> <color name="colorAccent">#D81B60</color>
<color name="Ruby">#701516</color>
<color name="Java">#b07219</color>
<color name="ObjectiveC">#438eff</color>
<color name="JavaScript">#f1e05a</color>
<color name="CSS">#563d7c</color>
<color name="Shell">#89e051</color>
</resources> </resources>

View File

@@ -1,3 +1,6 @@
<resources> <resources>
<string name="app_name">SquareGithubRepo</string> <string name="app_name">SquareGithubRepo</string>
<string name="search_title">Search</string>
</resources> </resources>