Commit 48e7cbbb authored by Nihar Thakkar's avatar Nihar Thakkar
Browse files

Revert some changes, improve data binding, create new ViewModels, Models and interfaces

parent c74a046c
......@@ -26,6 +26,7 @@ android {
}
dependencies {
def lifecycle_version = "1.1.1"
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:27.1.1'
......@@ -33,6 +34,7 @@ dependencies {
implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support:preference-v7:27.1.1'
implementation 'com.android.support:recyclerview-v7:27.1.1'
implementation "android.arch.lifecycle:extensions:$lifecycle_version"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
......
......@@ -16,22 +16,23 @@ import io.eelo.appinstaller.updates.UpdatesFragment
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemSelectedListener {
private val settings = Settings()
private var currentFragment: Fragment? = null
private val homeFragment = HomeFragment()
private val categoriesFragment = CategoriesFragment()
private val searchFragment = SearchFragment.newInstance(settings)
private val searchFragment = SearchFragment()
private val updatesFragment = UpdatesFragment()
private val settingsFragment = SettingsFragment()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
settings.context = applicationContext
settings.serverPath = ""
settings.APKsFolder = ""
settings.resultsPerPage = 10
// Show the home fragment by default
showFragment(homeFragment)
bottom_navigation_view.setOnNavigationItemSelectedListener(this)
// Disable shifting of nav bar items
removeShiftMode(bottom_navigation_view)
}
......@@ -66,6 +67,7 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
.beginTransaction()
.replace(R.id.frame_layout, fragment)
.commit()
currentFragment = fragment
}
@SuppressLint("RestrictedApi")
......
package io.eelo.appinstaller.categories
class CategoriesModel : CategoriesModelInterface {
}
\ No newline at end of file
package io.eelo.appinstaller.categories
interface CategoriesModelInterface {
}
\ No newline at end of file
package io.eelo.appinstaller.categories
class CategoriesViewModel : CategoriesViewModelInterface {
}
\ No newline at end of file
package io.eelo.appinstaller.categories
interface CategoriesViewModelInterface {
}
\ No newline at end of file
package io.eelo.appinstaller.home
class HomeModel : HomeModelInterface {
}
\ No newline at end of file
package io.eelo.appinstaller.home
interface HomeModelInterface {
}
\ No newline at end of file
package io.eelo.appinstaller.home
class HomeViewModel : HomeViewModelInterface {
}
\ No newline at end of file
package io.eelo.appinstaller.home
interface HomeViewModelInterface {
}
\ No newline at end of file
package io.eelo.appinstaller.search
import android.support.v7.widget.RecyclerView
import android.view.View
import android.widget.Button
import android.widget.ImageView
import android.widget.RatingBar
import android.widget.TextView
import io.eelo.appinstaller.application.ApplicationManager
import io.eelo.appinstaller.application.ApplicationStateListener
import io.eelo.appinstaller.application.Downloader
import io.eelo.appinstaller.application.State
import kotlinx.android.synthetic.main.application_list_item.view.*
class AppViewHolder(val view: View) : RecyclerView.ViewHolder(view), ApplicationStateListener {
private val icon: ImageView = view.app_icon
private val title: TextView = view.app_title
private val author: TextView = view.app_author
private val ratingBar: RatingBar = view.app_rating_bar
private val rating: TextView = view.app_rating
private val privacyScore: TextView = view.app_privacy_score
private val app_install: Button = view.app_install
var app: ApplicationManager? = null
init {
app_install.setOnClickListener { app?.buttonClicked() }
}
fun changeApp(app: ApplicationManager) {
title.text = app.data.name
author.text = app.data.author
ratingBar.rating = app.data.stars
rating.text = app.data.stars.toString()
privacyScore.text = (app.data.privacyScore.toString() + "%")
this.app?.setListener(ApplicationStateListener.EMPTY())
this.app = app
app.setListener(this)
// TODO("change icon !")
}
override fun stateChanged(state: State) {
app_install.text = state.buttonText
}
override fun downloading(downloader: Downloader) {
// TODO("not implemented")
}
override fun anErrorHasOccurred() {
// TODO("not implemented")
}
}
\ No newline at end of file
......@@ -2,20 +2,43 @@ package io.eelo.appinstaller.search
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.RatingBar
import android.widget.TextView
import io.eelo.appinstaller.R
import io.eelo.appinstaller.application.ApplicationManager
import io.eelo.appinstaller.application.Application
import kotlinx.android.synthetic.main.application_list_item.view.*
class ApplicationListAdapter(private val appList: List<ApplicationManager>) : RecyclerView.Adapter<AppViewHolder>() {
class ApplicationListAdapter(private val appList: ArrayList<Application>) :
RecyclerView.Adapter<ApplicationListAdapter.AppViewHolder>() {
// Define the view holder
class AppViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
val icon: ImageView = view.app_icon
val title: TextView = view.app_title
val author: TextView = view.app_author
val ratingBar: RatingBar = view.app_rating_bar
val rating: TextView = view.app_rating
val privacyScore: TextView = view.app_privacy_score
}
// Create a view holder for the list item
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AppViewHolder {
val listItemContainer = LayoutInflater.from(parent.context).inflate(R.layout.application_list_item, parent, false)
return AppViewHolder(listItemContainer)
}
// Set properties of views in the view holder
override fun onBindViewHolder(holder: AppViewHolder, position: Int) {
holder.changeApp(appList.get(position))
holder.title.text = appList[position].data.name
holder.author.text = appList[position].data.author
holder.ratingBar.rating = appList[position].data.stars
holder.rating.text = appList[position].data.stars.toString()
holder.privacyScore.text = appList[position].data.privacyScore.toString() + "%"
}
// Size of the app list
override fun getItemCount() = appList.size
}
package io.eelo.appinstaller.search
import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModelProviders
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.widget.CursorAdapter
import android.support.v4.widget.SimpleCursorAdapter
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.SearchView
import android.view.*
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import io.eelo.appinstaller.R
import io.eelo.appinstaller.Settings
import io.eelo.appinstaller.application.ApplicationManager
import android.provider.BaseColumns
import android.database.MatrixCursor
class SearchFragment : Fragment(), SearchView.OnQueryTextListener {
private var settings: Settings? = null
private var searchViewModel : SearchModel? = null
private var searchView : SearchView? = null
private var recyclerView : RecyclerView? = null
companion object {
fun newInstance(settings: Settings): SearchFragment {
val fragment = SearchFragment()
fragment.settings = settings
return fragment
}
}
class SearchFragment : Fragment(), SearchView.OnQueryTextListener, SearchView.OnSuggestionListener {
private lateinit var searchViewModel: SearchViewModel
private lateinit var searchView: SearchView
private val SUGGESTION_KEY = "suggestion"
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_search, container, false)
searchViewModel = SearchModel(settings!!)
searchViewModel = ViewModelProviders.of(this).get(SearchViewModel::class.java)
searchView = view.findViewById(R.id.search_view)
recyclerView = view.findViewById(R.id.app_list)
val recyclerView = view.findViewById<RecyclerView>(R.id.app_list)
val viewManager = LinearLayoutManager(context)
recyclerView!!.setHasFixedSize(true)
recyclerView!!.layoutManager = LinearLayoutManager(context)
refreshList(ArrayList())
// Initialise search view
val from = arrayOf(SUGGESTION_KEY)
val to = intArrayOf(android.R.id.text1)
searchView.suggestionsAdapter = SimpleCursorAdapter(context,
android.R.layout.simple_list_item_1, null, from, to,
CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER)
populateSuggestionsAdapter(searchViewModel.getSuggestions().value!!)
searchView!!.setOnQueryTextListener(this)
// Initialise recycler view
recyclerView.setHasFixedSize(true)
recyclerView.layoutManager = viewManager
recyclerView.adapter = ApplicationListAdapter(searchViewModel.getApplications().value!!)
return view
}
// Bind search view suggestions adapter to search suggestions list in view model
searchViewModel.getSuggestions().observe(this, Observer {
populateSuggestionsAdapter(it!!)
})
// Bind recycler view adapter to search results list in view model
searchViewModel.getApplications().observe(this, Observer {
recyclerView.adapter.notifyDataSetChanged()
})
// Handle suggestion clicks
searchView.setOnSuggestionListener(this)
private fun refreshList(apps: List<ApplicationManager>) {
recyclerView!!.adapter = ApplicationListAdapter(apps)
// Handle search queries
searchView.setOnQueryTextListener(this)
return view
}
override fun onQueryTextSubmit(query: String?): Boolean {
val apps = searchViewModel!!.search(query!!).apps
refreshList(apps)
return false
query?.let {
searchViewModel.onSearchQuerySubmitted(it)
}
return true
}
override fun onQueryTextChange(newText: String?): Boolean {
return false
searchView.query?.let {
searchViewModel.onSearchQueryChanged(it.toString())
}
return true
}
override fun onSuggestionSelect(position: Int): Boolean {
return true
}
override fun onSuggestionClick(position: Int): Boolean {
searchView.setQuery(searchViewModel.getSuggestions().value!![position], true)
return true
}
private fun populateSuggestionsAdapter(suggestions: ArrayList<String>) {
val cursor = MatrixCursor(arrayOf(BaseColumns._ID, SUGGESTION_KEY))
for (i in 0 until suggestions.size) {
cursor.addRow(arrayOf(i, suggestions[i]))
}
searchView.suggestionsAdapter.changeCursor(cursor)
}
}
package io.eelo.appinstaller.search
import io.eelo.appinstaller.Settings
import android.arch.lifecycle.MutableLiveData
import io.eelo.appinstaller.application.Application
class SearchModel(private val settings: Settings) {
private val searchElements = ArrayList<SearchElement>()
class SearchModel : SearchModelInterface {
val suggestionList = MutableLiveData<ArrayList<String>>()
val applicationList = MutableLiveData<ArrayList<Application>>()
fun search(query: String): SearchElement {
val element = SearchElement(query, settings)
searchElements.add(element)
element.search()
return element
init {
if (suggestionList.value == null) {
suggestionList.value = ArrayList()
}
if (applicationList.value == null) {
applicationList.value = ArrayList()
}
}
fun loadMore() {
searchElements.last().search()
override fun searchSuggestions(searchQuery: String) {
// TODO Get search query suggestions
}
fun back(): SearchElement? {
if (searchElements.isEmpty()) {
return null
}
searchElements.removeAt(searchElements.lastIndex)
return searchElements.last()
override fun search(searchQuery: String) {
// TODO Search for applications
// Jo Please start your search from here.
// Once the search is complete and you receive a callback,
// update the applicationList variable (applicationList.value).
}
override fun install(application: Application) {
// TODO Install APK
}
}
......@@ -3,7 +3,9 @@ package io.eelo.appinstaller.search
import io.eelo.appinstaller.application.Application
interface SearchModelInterface {
fun searchSuggestions(searchQuery: String)
fun search(searchQuery: String)
fun install(application: Application)
}
\ No newline at end of file
}
package io.eelo.appinstaller.search
import android.arch.lifecycle.MutableLiveData
import android.arch.lifecycle.ViewModel
import io.eelo.appinstaller.application.Application
class SearchViewModel : ViewModel(), SearchViewModelInterface {
private val searchModel = SearchModel()
fun getSuggestions(): MutableLiveData<ArrayList<String>> {
return searchModel.suggestionList
}
fun getApplications(): MutableLiveData<ArrayList<Application>> {
return searchModel.applicationList
}
override fun onSearchQueryChanged(searchQuery: String) {
searchModel.searchSuggestions(searchQuery)
}
override fun onSearchQuerySubmitted(searchQuery: String) {
searchModel.search(searchQuery)
}
override fun onApplicationClick(application: Application) {
// TODO Show detailed view of application
}
override fun onInstallClick(application: Application) {
searchModel.install(application)
}
}
......@@ -3,7 +3,9 @@ package io.eelo.appinstaller.search
import io.eelo.appinstaller.application.Application
interface SearchViewModelInterface {
fun onSearchClick(searchQuery: String)
fun onSearchQueryChanged(searchQuery: String)
fun onSearchQuerySubmitted(searchQuery: String)
fun onApplicationClick(application: Application)
......
package io.eelo.appinstaller.updates
class UpdatesModel : UpdatesModelInterface {
}
\ No newline at end of file
package io.eelo.appinstaller.updates
interface UpdatesModelInterface {
}
\ No newline at end of file
package io.eelo.appinstaller.updates
class UpdatesViewModel : UpdatesViewModelInterface {
}
\ No newline at end of file
Supports Markdown
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