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

View File

@@ -8,7 +8,7 @@ android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.h_mal.myapplication"
minSdkVersion 15
minSdkVersion 23
targetSdkVersion 28
versionCode 1
versionName "1.0"
@@ -33,4 +33,5 @@ dependencies {
implementation 'com.squareup.okhttp3:okhttp:4.2.1'
implementation 'com.google.code.gson:gson:2.8.5'
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
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.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.Filter
import com.example.h_mal.myapplication.model.JsonObject
import kotlinx.android.synthetic.main.repo_list_item.view.*
//custom list adapter extends from array adater
class ListViewAdapter(context: Context, objects: MutableList<JsonObject>) :
ArrayAdapter<JsonObject>(context, 0, objects){
//populate each 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
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)
view?.name?.text = item?.name
view?.description?.text = item?.description
//set name and 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.os.Bundle
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.google.gson.Gson
import kotlinx.android.synthetic.main.activity_main.*
@@ -12,49 +16,101 @@ import java.io.IOException
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?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
thecontext = this
//begin populating list
executeTask()
//set a listener for the swipe to refresh
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{
//populate list when pulling to refresh
executeTask()
}
fun executeTask(){
//clear list before populating
list_view.adapter = null
//create url from url string urlstring
val url = Request.Builder().url(urlString).build()
//create a okhttpclient for a get request from url
val client = OkHttpClient()
//call the url and retrieve its callback
client.newCall(url).enqueue(object: Callback {
//failure of retrieval callback
override fun onFailure(call: Call, e: IOException) {
//print error to log
System.err.println(e)
//if swipe refresh is refreshing then stop
swipe_refresh.isRefreshing = false
//list is empty
}
//successful retrieval callback
override fun onResponse(call: Call, response: Response) {
//get the JSON from the body
val urlResponse = response.body?.string()
//print the response to the logs
println("response = $urlResponse")
//create gson object
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()
runOnUiThread{
list_view.adapter = ListViewAdapter(thecontext, objectList)
swipe_refresh.isRefreshing = false
if (objectList.size >0){
//update the ui
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,
@SerializedName("language")
var language : String? = null,
@SerializedName("created_at")
var date : String? = null,
@SerializedName("html_url")
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>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"/>
</android.support.constraint.ConstraintLayout>

View File

@@ -1,18 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:hint="name"
android:layout_margin="12dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" tools:layout_editor_absoluteY="16dp"
tools:layout_editor_absoluteX="16dp" android:id="@+id/name"/>
<TextView
android:hint="description"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_below="@id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content" tools:layout_editor_absoluteY="44dp"
tools:layout_editor_absoluteX="16dp" android:id="@+id/description"/>
</RelativeLayout>
android:layout_marginTop="6dp"
android:layout_marginRight="12dp"
android:layout_marginBottom="6dp"
app:cardCornerRadius="12dp">
<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"?>
<resources>
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorPrimary">#30ABC5</color>
<color name="colorPrimaryDark">#247E91</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>

View File

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