Add code documentation (classes), Improve variable names

- Rename "action" to "intention", as "action" was used for two things. 
Now it only describes swipe or click actions.
- other minor style improvements
This commit is contained in:
Finn M Glas 2020-06-19 09:45:16 +02:00
parent 90e1f8893b
commit 840ef1f110
No known key found for this signature in database
GPG key ID: 902A30146014DFBF
17 changed files with 134 additions and 63 deletions

View file

@ -19,15 +19,19 @@ import android.widget.Button
import android.widget.ImageView import android.widget.ImageView
import android.widget.Toast import android.widget.Toast
import com.finnmglas.launcher.list.ListActivity import com.finnmglas.launcher.list.ListActivity
import com.finnmglas.launcher.list.apps.AppsRecyclerAdapter
import com.finnmglas.launcher.settings.SettingsActivity import com.finnmglas.launcher.settings.SettingsActivity
import com.finnmglas.launcher.settings.intendedSettingsPause import com.finnmglas.launcher.settings.intendedSettingsPause
import com.finnmglas.launcher.tutorial.TutorialActivity import com.finnmglas.launcher.tutorial.TutorialActivity
import kotlin.math.roundToInt import kotlin.math.roundToInt
/** Preferences (global, initialised when app is started) */ /* Preferences (global, initialised when app is started) */
lateinit var launcherPreferences: SharedPreferences lateinit var launcherPreferences: SharedPreferences
/** Variables containing settings */ /* Objects used by multiple activities */
lateinit var appListViewAdapter: AppsRecyclerAdapter
/* Variables containing settings */
val displayMetrics = DisplayMetrics() val displayMetrics = DisplayMetrics()
var upApp = "" var upApp = ""
@ -47,14 +51,14 @@ var background : Bitmap? = null
var dominantColor = 0 var dominantColor = 0
var vibrantColor = 0 var vibrantColor = 0
/** REQUEST CODES */ /* REQUEST CODES */
const val REQUEST_PICK_IMAGE = 1 const val REQUEST_PICK_IMAGE = 1
const val REQUEST_CHOOSE_APP = 2 const val REQUEST_CHOOSE_APP = 2
const val REQUEST_UNINSTALL = 3 const val REQUEST_UNINSTALL = 3
const val REQUEST_PERMISSION_STORAGE = 4 const val REQUEST_PERMISSION_STORAGE = 4
/** Animate */ /* Animate */
// Taken from https://stackoverflow.com/questions/47293269 // Taken from https://stackoverflow.com/questions/47293269
fun View.blink( fun View.blink(
@ -125,7 +129,7 @@ fun View.fadeRotateOut(duration: Long = 500L) {
startAnimation(combined) startAnimation(combined)
} }
/** Activity related */ /* Activity related */
fun isInstalled(uri: String, context: Context): Boolean { fun isInstalled(uri: String, context: Context): Boolean {
try { try {
@ -194,7 +198,7 @@ fun openNewTabWindow(urls: String, context : Context) {
context.startActivity(intents) context.startActivity(intents)
} }
/** Settings related functions */ /* Settings related functions */
fun getSavedTheme(context : Context) : String { fun getSavedTheme(context : Context) : String {
return launcherPreferences.getString("theme", "finn").toString() return launcherPreferences.getString("theme", "finn").toString()
@ -224,7 +228,7 @@ fun openTutorial(activity: Activity){
fun openAppsList(activity: Activity){ fun openAppsList(activity: Activity){
val intent = Intent(activity, ListActivity::class.java) val intent = Intent(activity, ListActivity::class.java)
intent.putExtra("action", "view") intent.putExtra("intention", "view")
intendedSettingsPause = true intendedSettingsPause = true
activity.startActivity(intent) activity.startActivity(intent)
} }
@ -337,7 +341,7 @@ fun pickDefaultApp(action: String, context: Context) : Pair<String, String>{
return Pair(context.getString(R.string.none_found), "") return Pair(context.getString(R.string.none_found), "")
} }
/** Bitmaps */ /* Bitmaps */
fun setButtonColor(btn: Button, color: Int) { fun setButtonColor(btn: Button, color: Int) {
if (Build.VERSION.SDK_INT >= 29) if (Build.VERSION.SDK_INT >= 29)

View file

@ -17,9 +17,18 @@ import java.util.*
import kotlin.concurrent.fixedRateTimer import kotlin.concurrent.fixedRateTimer
import kotlin.math.abs import kotlin.math.abs
// used in `ListFragmentApps` /**
lateinit var appListViewAdapter: AppsRecyclerAdapter * [HomeActivity] is the actual application Launcher,
* what makes this application special / unique.
*
* In this activity we display the date and time,
* and we listen for actions like tapping, swiping or button presses.
*
* As it also is the first thing that is started when someone opens Launcher,
* it also contains some logic related to the overall application:
* - Setting global variables (preferences etc.)
* - Opening the [TutorialActivity] on new installations
*/
class HomeActivity: UIObject, AppCompatActivity(), class HomeActivity: UIObject, AppCompatActivity(),
GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener { GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener {
@ -33,7 +42,6 @@ class HomeActivity: UIObject, AppCompatActivity(),
private var settingsIconShown = false private var settingsIconShown = false
/** Activity Lifecycle functions */
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -104,8 +112,6 @@ class HomeActivity: UIObject, AppCompatActivity(),
hideSettingsIcon() hideSettingsIcon()
} }
/** Touch- and Key-related functions to start activities */
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK) { if (settingsIconShown) hideSettingsIcon() } if (keyCode == KeyEvent.KEYCODE_BACK) { if (settingsIconShown) hideSettingsIcon() }
else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP)

View file

@ -3,6 +3,10 @@ package com.finnmglas.launcher
import android.app.Activity import android.app.Activity
import android.view.WindowManager import android.view.WindowManager
/**
* An interface implemented by every [Activity], Fragment etc. in Launcher.
* It handles themes and window flags - a useful abstraction as it is the same everywhere.
*/
interface UIObject { interface UIObject {
fun onStart() { fun onStart() {
if (this is Activity){ if (this is Activity){

View file

@ -21,10 +21,16 @@ import com.finnmglas.launcher.list.other.ListFragmentOther
var intendedChoosePause = false // know when to close var intendedChoosePause = false // know when to close
// TODO: Better solution for this (used in list-fragments) // TODO: Better solution for this (used in list-fragments)
var action = "view" var intention = "view"
var forApp = "" var forApp = ""
/**
* The [ListActivity] is the most general purpose activity in Launcher:
* - used to view all apps and edit their settings
* - used to choose an app / intent to be launched
*
* The activity itself can also be chosen to be launched as an action.
*/
class ListActivity : AppCompatActivity(), UIObject { class ListActivity : AppCompatActivity(), UIObject {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -81,17 +87,17 @@ class ListActivity : AppCompatActivity(), UIObject {
// get info about which action this activity is open for // get info about which action this activity is open for
val bundle = intent.extras val bundle = intent.extras
if (bundle != null) { if (bundle != null) {
action = bundle.getString("action")!! // why choose an app intention = bundle.getString("intention")!! // why choose an app
if (action != "view") if (intention != "view")
forApp = bundle.getString("forApp")!! // which app we choose forApp = bundle.getString("forApp")!! // which app we choose
} }
// Hide tabs for the "view" action // Hide tabs for the "view" action
if (action == "view") { if (intention == "view") {
list_tabs.visibility = View.GONE list_tabs.visibility = View.GONE
} }
when (action) { when (intention) {
"view" -> list_heading.text = getString(R.string.choose_title_view) "view" -> list_heading.text = getString(R.string.choose_title_view)
"pick" -> list_heading.text = getString(R.string.choose_title) "pick" -> list_heading.text = getString(R.string.choose_title)
} }
@ -109,7 +115,10 @@ private val TAB_TITLES = arrayOf(
R.string.choose_tab_other R.string.choose_tab_other
) )
/** Returns the fragment corresponding to the selected tab.*/ /**
* The [ListSectionsPagerAdapter] returns the fragment,
* which corresponds to the selected tab in [ListActivity].
*/
class ListSectionsPagerAdapter(private val context: Context, fm: FragmentManager) class ListSectionsPagerAdapter(private val context: Context, fm: FragmentManager)
: FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
@ -126,7 +135,7 @@ class ListSectionsPagerAdapter(private val context: Context, fm: FragmentManager
} }
override fun getCount(): Int { override fun getCount(): Int {
return when (action) { return when (intention) {
"view" -> 1 "view" -> 1
else -> 2 else -> 2
} }

View file

@ -3,7 +3,9 @@ package com.finnmglas.launcher.list.apps
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
/** /**
* Stores information used in [AppsRecyclerAdapter] rows. * Stores information used to create [AppsRecyclerAdapter] rows.
*
* Represents an app installed on the users device.
*/ */
class AppInfo { class AppInfo {
var label: CharSequence? = null var label: CharSequence? = null

View file

@ -16,7 +16,17 @@ import com.finnmglas.launcher.*
import com.finnmglas.launcher.libraries.* import com.finnmglas.launcher.libraries.*
import com.finnmglas.launcher.list.intendedChoosePause import com.finnmglas.launcher.list.intendedChoosePause
class AppsRecyclerAdapter(val activity: Activity, val action: String? = "view", val forApp: String? = ""): /**
* A [RecyclerView] (efficient scrollable list) containing all apps on the users device.
* The apps details are represented by [AppInfo].
*
* @param activity - the activity this is in
* @param intention - why the list is displayed ("view", "pick")
* @param forApp - the action which an app is chosen for (when the intention is "pick")
*/
class AppsRecyclerAdapter(val activity: Activity,
val intention: String? = "view",
val forApp: String? = ""):
RecyclerView.Adapter<AppsRecyclerAdapter.ViewHolder>() { RecyclerView.Adapter<AppsRecyclerAdapter.ViewHolder>() {
private val appsList: MutableList<AppInfo> private val appsList: MutableList<AppInfo>
@ -32,7 +42,7 @@ class AppsRecyclerAdapter(val activity: Activity, val action: String? = "view",
val context: Context = v.context val context: Context = v.context
val appPackageName = appsList[pos].packageName.toString() val appPackageName = appsList[pos].packageName.toString()
when (action){ when (intention){
"view" -> { "view" -> {
val launchIntent: Intent = context.packageManager val launchIntent: Intent = context.packageManager
.getLaunchIntentForPackage(appPackageName)!! .getLaunchIntentForPackage(appPackageName)!!
@ -65,7 +75,7 @@ class AppsRecyclerAdapter(val activity: Activity, val action: String? = "view",
) )
// decide when to show the options popup menu about // decide when to show the options popup menu about
if (isSystemApp || action == "pick") { if (isSystemApp || intention == "pick") {
viewHolder.menuDots.visibility = View.INVISIBLE viewHolder.menuDots.visibility = View.INVISIBLE
} }
else { else {

View file

@ -8,19 +8,20 @@ import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.finnmglas.launcher.R import com.finnmglas.launcher.R
import com.finnmglas.launcher.UIObject import com.finnmglas.launcher.UIObject
import com.finnmglas.launcher.list.action import com.finnmglas.launcher.list.intention
import com.finnmglas.launcher.list.forApp import com.finnmglas.launcher.list.forApp
import com.finnmglas.launcher.dominantColor import com.finnmglas.launcher.dominantColor
import com.finnmglas.launcher.getSavedTheme import com.finnmglas.launcher.getSavedTheme
import kotlinx.android.synthetic.main.list_apps.* import kotlinx.android.synthetic.main.list_apps.*
/** The 'Apps' Tab associated Fragment for the List */ /**
* The [ListFragmentApps] is used as a tab in ListActivity.
*
* It is a list of all installed applications that are can be launched.
*/
class ListFragmentApps : Fragment(), UIObject { class ListFragmentApps : Fragment(), UIObject {
/** Lifecycle functions */
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
@ -47,7 +48,7 @@ class ListFragmentApps : Fragment(), UIObject {
// improve performance (since content changes don't change the layout size) // improve performance (since content changes don't change the layout size)
setHasFixedSize(true) setHasFixedSize(true)
layoutManager = LinearLayoutManager(context) layoutManager = LinearLayoutManager(context)
adapter = AppsRecyclerAdapter(activity!!, action, forApp) adapter = AppsRecyclerAdapter(activity!!, intention, forApp)
} }
} }
} }

View file

@ -11,12 +11,14 @@ import com.finnmglas.launcher.dominantColor
import com.finnmglas.launcher.getSavedTheme import com.finnmglas.launcher.getSavedTheme
import kotlinx.android.synthetic.main.list_other.* import kotlinx.android.synthetic.main.list_other.*
/** The 'Other' Tab associated Fragment in the Chooser */ /**
* The [ListFragmentOther] is used as a tab in ListActivity,
* when the `intention` for launching the ListActivity was to select something to be launched.
*
* It lists `other` things like internal activities to be launched as an action.
*/
class ListFragmentOther : Fragment() { class ListFragmentOther : Fragment() {
/** Lifecycle functions */
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?

View file

@ -2,6 +2,11 @@ package com.finnmglas.launcher.list.other
/** /**
* Stores information used in [OtherRecyclerAdapter] rows. * Stores information used in [OtherRecyclerAdapter] rows.
*
* Represents an `other` action - something that can be selected to be launched
* when an action is recognized.
*
* @param data - a string identifying the thing to be launched
*/ */
class OtherInfo(label: String, data: String, icon: String) { class OtherInfo(label: String, data: String, icon: String) {
var label: CharSequence? = label var label: CharSequence? = label

View file

@ -12,7 +12,13 @@ import com.finnmglas.launcher.REQUEST_CHOOSE_APP
import com.finnmglas.launcher.libraries.* import com.finnmglas.launcher.libraries.*
import com.finnmglas.launcher.list.forApp import com.finnmglas.launcher.list.forApp
/* Will only be used if an app / action is picked */ /**
* The [OtherRecyclerAdapter] will only be displayed in the ListActivity,
* if an app / intent / etc. is picked to be launched when an action is recognized.
*
* It lists `other` things to be launched that are not really represented by a URI,
* rather by Launcher- internal conventions.
*/
class OtherRecyclerAdapter(val activity: Activity): class OtherRecyclerAdapter(val activity: Activity):
RecyclerView.Adapter<OtherRecyclerAdapter.ViewHolder>() { RecyclerView.Adapter<OtherRecyclerAdapter.ViewHolder>() {

View file

@ -13,16 +13,23 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter import androidx.fragment.app.FragmentPagerAdapter
import com.finnmglas.launcher.settings.actions.SettingsFragmentActions import com.finnmglas.launcher.settings.actions.SettingsFragmentActions
import com.finnmglas.launcher.settings.meta.SettingsFragmentMeta
import com.finnmglas.launcher.settings.theme.SettingsFragmentTheme import com.finnmglas.launcher.settings.theme.SettingsFragmentTheme
import com.finnmglas.launcher.settings.meta.SettingsFragmentMeta
var intendedSettingsPause = false // know when to close var intendedSettingsPause = false // know when to close
/**
* The [SettingsActivity] is a tabbed activity:
*
* | Actions | Choose apps or intents to be launched | [SettingsFragmentActions] |
* | Theme | Select a theme / Customize | [SettingsFragmentTheme] |
* | Meta | About Launcher / Contact etc. | [SettingsFragmentMeta] |
*
* Settings are closed automatically if the activity goes `onPause` unexpectedly.
*/
class SettingsActivity: AppCompatActivity(), UIObject { class SettingsActivity: AppCompatActivity(), UIObject {
/** Activity Lifecycle functions */
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -96,7 +103,6 @@ private val TAB_TITLES = arrayOf(
R.string.settings_tab_launcher R.string.settings_tab_launcher
) )
/** Returns the fragment corresponding to the selected tab.*/
class SettingsSectionsPagerAdapter(private val context: Context, fm: FragmentManager) class SettingsSectionsPagerAdapter(private val context: Context, fm: FragmentManager)
: FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {

View file

@ -2,9 +2,13 @@ package com.finnmglas.launcher.settings.actions
/** /**
* Stores information used in [ActionsRecyclerAdapter] rows. * Stores information used in [ActionsRecyclerAdapter] rows.
*
* Represents an action - something to be triggered by swiping, clicking etc.
*
* @param data - a string identifying the app / action / intent to be launched
*/ */
class ActionInfo(actionText: CharSequence, actionName: CharSequence, content: CharSequence) { class ActionInfo(actionText: CharSequence, actionName: CharSequence, data: CharSequence) {
val actionName: CharSequence? = actionName val actionName: CharSequence? = actionName
val actionText: CharSequence? = actionText val actionText: CharSequence? = actionText
val content: CharSequence? = content val data: CharSequence? = data
} }

View file

@ -37,7 +37,7 @@ class ActionsRecyclerAdapter(val activity: Activity):
override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) { override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
val actionText = actionsList[i].actionText val actionText = actionsList[i].actionText
val actionName = actionsList[i].actionName val actionName = actionsList[i].actionName
val content = actionsList[i].content val content = actionsList[i].data
viewHolder.textView.text = actionText viewHolder.textView.text = actionText
@ -133,7 +133,7 @@ class ActionsRecyclerAdapter(val activity: Activity):
/* */ /* */
private fun chooseApp(forAction: String) { private fun chooseApp(forAction: String) {
val intent = Intent(activity, ListActivity::class.java) val intent = Intent(activity, ListActivity::class.java)
intent.putExtra("action", "pick") intent.putExtra("intention", "pick")
intent.putExtra("forApp", forAction) // for which action we choose the app intent.putExtra("forApp", forAction) // for which action we choose the app
intendedSettingsPause = true intendedSettingsPause = true
activity.startActivityForResult(intent, activity.startActivityForResult(intent,

View file

@ -16,12 +16,16 @@ import com.finnmglas.launcher.settings.intendedSettingsPause
import kotlinx.android.synthetic.main.settings_actions.* import kotlinx.android.synthetic.main.settings_actions.*
/** The 'Apps' Tab associated Fragment in Settings */ /**
* The [SettingsFragmentActions] is a used as a tab in the SettingsActivity.
*
* It is used to change Apps / Intents to be launched when a specific action
* is triggered.
* It also allows the user to view all apps ([ListActivity]) or install new ones.
*/
class SettingsFragmentActions : Fragment(), UIObject { class SettingsFragmentActions : Fragment(), UIObject {
/** Lifecycle functions */
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
@ -65,7 +69,7 @@ class SettingsFragmentActions : Fragment(), UIObject {
// App management buttons // App management buttons
settings_actions_button_view_apps.setOnClickListener{ settings_actions_button_view_apps.setOnClickListener{
val intent = Intent(this.context, ListActivity::class.java) val intent = Intent(this.context, ListActivity::class.java)
intent.putExtra("action", "view") intent.putExtra("intention", "view")
intendedSettingsPause = true intendedSettingsPause = true
startActivity(intent) startActivity(intent)
} }

View file

@ -17,12 +17,16 @@ import com.finnmglas.launcher.tutorial.TutorialActivity
import com.finnmglas.launcher.settings.intendedSettingsPause import com.finnmglas.launcher.settings.intendedSettingsPause
import kotlinx.android.synthetic.main.settings_meta.* import kotlinx.android.synthetic.main.settings_meta.*
/** The 'Meta' Tab associated Fragment in Settings */ /**
* The [SettingsFragmentMeta] is a used as a tab in the SettingsActivity.
*
* It is used to change settings and access resources about Launcher,
* that are not directly related to the behaviour of the app itself.
*
* (greek `meta` = above, next level)
*/
class SettingsFragmentMeta : Fragment(), UIObject { class SettingsFragmentMeta : Fragment(), UIObject {
/** Lifecycle functions */
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
@ -35,8 +39,6 @@ class SettingsFragmentMeta : Fragment(), UIObject {
super<UIObject>.onStart() super<UIObject>.onStart()
} }
/** Extra functions */
// Rate App // Rate App
// Just copied code from https://stackoverflow.com/q/10816757/12787264 // Just copied code from https://stackoverflow.com/q/10816757/12787264
// that is how we write good software ^^ // that is how we write good software ^^

View file

@ -18,11 +18,13 @@ import com.finnmglas.launcher.*
import com.finnmglas.launcher.settings.intendedSettingsPause import com.finnmglas.launcher.settings.intendedSettingsPause
import kotlinx.android.synthetic.main.settings_theme.* import kotlinx.android.synthetic.main.settings_theme.*
/** The 'Theme' Tab associated Fragment in Settings */ /**
* The [SettingsFragmentTheme] is a used as a tab in the SettingsActivity.
*
* It is used to change themes, select wallpapers ... theme related stuff
*/
class SettingsFragmentTheme : Fragment(), UIObject { class SettingsFragmentTheme : Fragment(), UIObject {
/** Lifecycle functions */
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
@ -44,8 +46,6 @@ class SettingsFragmentTheme : Fragment(), UIObject {
} }
} }
/** Extra functions */
private fun letUserPickImage(crop: Boolean = false) { private fun letUserPickImage(crop: Boolean = false) {
val intent = Intent() val intent = Intent()
intent.type = "image/*" intent.type = "image/*"

View file

@ -8,7 +8,13 @@ import androidx.appcompat.app.AppCompatActivity
import com.finnmglas.launcher.* import com.finnmglas.launcher.*
import kotlinx.android.synthetic.main.tutorial.* import kotlinx.android.synthetic.main.tutorial.*
/**
* The [TutorialActivity] is displayed automatically on new installations.
* It can also be opened from Settings.
*
* It tells the user about the concept behind launcher
* and helps with the setup process (on new installations)
*/
class TutorialActivity: AppCompatActivity(), UIObject { class TutorialActivity: AppCompatActivity(), UIObject {
private var menuNumber = 0 private var menuNumber = 0