diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 743d0fb..56806ce 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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' } diff --git a/app/src/main/java/com/example/h_mal/myapplication/ListViewAdapter.kt b/app/src/main/java/com/example/h_mal/myapplication/ListViewAdapter.kt index 0c355ad..2c15217 100644 --- a/app/src/main/java/com/example/h_mal/myapplication/ListViewAdapter.kt +++ b/app/src/main/java/com/example/h_mal/myapplication/ListViewAdapter.kt @@ -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) : ArrayAdapter(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 + } } } \ No newline at end of file diff --git a/app/src/main/java/com/example/h_mal/myapplication/MainActivity.kt b/app/src/main/java/com/example/h_mal/myapplication/MainActivity.kt index 82801e4..5ed2182 100644 --- a/app/src/main/java/com/example/h_mal/myapplication/MainActivity.kt +++ b/app/src/main/java/com/example/h_mal/myapplication/MainActivity.kt @@ -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::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 } } diff --git a/app/src/main/java/com/example/h_mal/myapplication/model/JsonObject.kt b/app/src/main/java/com/example/h_mal/myapplication/model/JsonObject.kt index a5636de..782fad6 100644 --- a/app/src/main/java/com/example/h_mal/myapplication/model/JsonObject.kt +++ b/app/src/main/java/com/example/h_mal/myapplication/model/JsonObject.kt @@ -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 ) diff --git a/app/src/main/res/drawable/ic_search_black_24dp.xml b/app/src/main/res/drawable/ic_search_black_24dp.xml new file mode 100644 index 0000000..affc7ba --- /dev/null +++ b/app/src/main/res/drawable/ic_search_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_search_white_24dp.xml b/app/src/main/res/drawable/ic_search_white_24dp.xml new file mode 100644 index 0000000..be5ad99 --- /dev/null +++ b/app/src/main/res/drawable/ic_search_white_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_sort_black_24dp.xml b/app/src/main/res/drawable/ic_sort_black_24dp.xml new file mode 100644 index 0000000..b3e29ab --- /dev/null +++ b/app/src/main/res/drawable/ic_sort_black_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index d5ac016..e7668de 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -19,4 +19,6 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/repo_list_item.xml b/app/src/main/res/layout/repo_list_item.xml index 3a7baf2..5ef36ef 100644 --- a/app/src/main/res/layout/repo_list_item.xml +++ b/app/src/main/res/layout/repo_list_item.xml @@ -1,18 +1,83 @@ - - - + + + - \ No newline at end of file + android:layout_marginTop="6dp" + android:layout_marginRight="12dp" + android:layout_marginBottom="6dp" + app:cardCornerRadius="12dp"> + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/menu.xml b/app/src/main/res/menu/menu.xml new file mode 100644 index 0000000..43c4bf7 --- /dev/null +++ b/app/src/main/res/menu/menu.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 69b2233..a20f354 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,6 +1,15 @@ - #008577 - #00574B + #30ABC5 + #247E91 #D81B60 + + #701516 + #b07219 + #438eff + #f1e05a + #563d7c + #89e051 + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 02c01f4..f30bd7a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,6 @@ SquareGithubRepo + Search + +