Create the UIObject interface

It is implemented by every visible object and serves as an abstraction, 
simplification.

Also: there only is one central sharedPreferences object (in 
`Functions.kt`). That makes the code way more readable.
This commit is contained in:
Finn M Glas 2020-06-18 09:25:38 +02:00
parent fc754b8c9a
commit 0c3a267d62
No known key found for this signature in database
GPG key ID: 902A30146014DFBF
16 changed files with 327 additions and 333 deletions

View file

@ -22,6 +22,8 @@ import com.finnmglas.launcher.settings.SettingsActivity
import com.finnmglas.launcher.settings.intendedSettingsPause import com.finnmglas.launcher.settings.intendedSettingsPause
import kotlin.math.roundToInt import kotlin.math.roundToInt
/** Preferences (Global, initialised when app is started) */
lateinit var launcherPreferences: SharedPreferences
/** Variables for all of the app */ /** Variables for all of the app */
var upApp = "" var upApp = ""
@ -332,13 +334,6 @@ fun pickDefaultApp(action: String, context: Context) : Pair<String, String>{
/** Bitmaps */ /** Bitmaps */
fun getDominantColor(bitmap: Bitmap?): Int {
val newBitmap = Bitmap.createScaledBitmap(bitmap!!, 1, 1, true)
val color = newBitmap.getPixel(0, 0)
newBitmap.recycle()
return color
}
fun setButtonColor(btn: Button, color: Int) { fun setButtonColor(btn: Button, color: Int) {
if (Build.VERSION.SDK_INT >= 29) if (Build.VERSION.SDK_INT >= 29)
btn.background.colorFilter = BlendModeColorFilter(color, BlendMode.MULTIPLY) btn.background.colorFilter = BlendModeColorFilter(color, BlendMode.MULTIPLY)

View file

@ -21,9 +21,8 @@ import kotlin.math.abs
// used for the apps drawer / menu (ChooseActivity) // used for the apps drawer / menu (ChooseActivity)
lateinit var viewAdapter: RecyclerView.Adapter<*> lateinit var viewAdapter: RecyclerView.Adapter<*>
lateinit var viewManager: RecyclerView.LayoutManager
class HomeActivity : AppCompatActivity(), class HomeActivity: UIObject, AppCompatActivity(),
GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener { GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener {
private var currentTheme = "" // keep track of theme changes private var currentTheme = "" // keep track of theme changes
@ -44,45 +43,23 @@ class HomeActivity : AppCompatActivity(),
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
// Preferences launcherPreferences = this.getSharedPreferences(
val sharedPref = this.getSharedPreferences(
getString(R.string.preference_file_key), Context.MODE_PRIVATE) getString(R.string.preference_file_key), Context.MODE_PRIVATE)
// Flags loadSettings(launcherPreferences)
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
)
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
currentTheme = getSavedTheme(this) currentTheme = getSavedTheme(this)
if (currentTheme == "custom") { // TODO: Don't use actual themes, rather create them on the fly
try {
background = MediaStore.Images.Media.getBitmap(this.contentResolver, Uri.parse(sharedPref.getString("background_uri", "")))
} catch (e: Exception) { }
if (background == null)
currentTheme = saveTheme(this, "finn")
}
setTheme( setTheme(
when (currentTheme) { when (getSavedTheme(this)) {
"dark" -> R.style.darkTheme "dark" -> R.style.darkTheme
"finn" -> R.style.finnmglasTheme "finn" -> R.style.finnmglasTheme
else -> R.style.customTheme else -> R.style.customTheme
} }
) )
setContentView(R.layout.home) setContentView(R.layout.home)
setTheme()
// Start by showing the settings icon setOnClicks()
showSettingsIcon()
// As older APIs somehow do not recognize the xml defined onClick
home_settings_icon.setOnClickListener() {
openSettings(this)
overridePendingTransition(R.anim.bottom_up, android.R.anim.fade_out)
}
// Load apps list first - speed up settings that way // Load apps list first - speed up settings that way
AsyncTask.execute { viewAdapter = AsyncTask.execute { viewAdapter =
@ -90,29 +67,23 @@ class HomeActivity : AppCompatActivity(),
} }
// First Startup // First Startup
if (!sharedPref.getBoolean("startedBefore", false)){ if (!launcherPreferences.getBoolean("startedBefore", false)){
startActivity(Intent(this, TutorialActivity::class.java)) startActivity(Intent(this, TutorialActivity::class.java))
tooltipTimer.cancel() tooltipTimer.cancel()
} }
} }
override fun onStart(){ override fun onStart(){
super.onStart() super<AppCompatActivity>.onStart()
super<UIObject>.onStart()
// Preferences
val sharedPref = this.getSharedPreferences(
getString(R.string.preference_file_key), Context.MODE_PRIVATE)
loadSettings(sharedPref)
if (currentTheme == "custom") {
home_settings_icon.setTextColor(vibrantColor)
}
mDetector = GestureDetectorCompat(this, this) mDetector = GestureDetectorCompat(this, this)
mDetector.setOnDoubleTapListener(this) mDetector.setOnDoubleTapListener(this)
windowManager.defaultDisplay.getMetrics(displayMetrics) windowManager.defaultDisplay.getMetrics(displayMetrics)
// for if the settings changed
loadSettings(launcherPreferences)
} }
override fun onResume() { override fun onResume() {
@ -161,15 +132,6 @@ class HomeActivity : AppCompatActivity(),
return true return true
} }
fun dateViewOnTouch(v: View) {
launch(calendarApp, this)
overridePendingTransition(0, 0)
}
fun timeViewOnTouch(v: View) {
launch(clockApp,this)
overridePendingTransition(0, 0)
}
override fun onFling(e1: MotionEvent, e2: MotionEvent, dX: Float, dY: Float): Boolean { override fun onFling(e1: MotionEvent, e2: MotionEvent, dX: Float, dY: Float): Boolean {
val width = displayMetrics.widthPixels val width = displayMetrics.widthPixels
@ -240,14 +202,43 @@ class HomeActivity : AppCompatActivity(),
settingsIconShown = false settingsIconShown = false
} }
fun settingsIconOnTouch(view: View){
openSettings(this)
}
override fun onTouchEvent(event: MotionEvent): Boolean { override fun onTouchEvent(event: MotionEvent): Boolean {
return if (mDetector.onTouchEvent(event)) { false } else { super.onTouchEvent(event) } return if (mDetector.onTouchEvent(event)) { false } else { super.onTouchEvent(event) }
} }
override fun setTheme() {
// Start by showing the settings icon
showSettingsIcon()
if (currentTheme == "custom") {
home_settings_icon.setTextColor(vibrantColor)
try {
background = MediaStore.Images.Media.getBitmap(this.contentResolver, Uri.parse(
launcherPreferences.getString("background_uri", "")))
} catch (e: Exception) { }
if (background == null)
currentTheme = saveTheme(this, "finn")
}
}
override fun setOnClicks() {
home_settings_icon.setOnClickListener() {
openSettings(this)
overridePendingTransition(R.anim.bottom_up, android.R.anim.fade_out)
}
home_date_view.setOnClickListener() {
launch(calendarApp, this)
overridePendingTransition(0, 0)
}
home_time_view.setOnClickListener() {
launch(clockApp,this)
overridePendingTransition(0, 0)
}
}
/* TODO: Remove those. For now they are necessary /* TODO: Remove those. For now they are necessary
* because this inherits from GestureDetector.OnGestureListener */ * because this inherits from GestureDetector.OnGestureListener */
override fun onDoubleTapEvent(event: MotionEvent): Boolean { return false } override fun onDoubleTapEvent(event: MotionEvent): Boolean { return false }

View file

@ -0,0 +1,18 @@
package com.finnmglas.launcher
import android.app.Activity
import android.view.WindowManager
interface UIObject {
fun onStart() {
if (this is Activity){
window.setFlags(0,0) // clear flags
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
}
fun setTheme()
fun setOnClicks()
fun configure() {}
}

View file

@ -4,7 +4,6 @@ import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.view.WindowManager
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
@ -17,8 +16,8 @@ import android.content.Context
import androidx.fragment.app.Fragment 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.list.apps.ChooseFragmentApps import com.finnmglas.launcher.list.apps.ListFragmentApps
import com.finnmglas.launcher.list.other.ChooseFragmentOther import com.finnmglas.launcher.list.other.ListFragmentOther
var intendedChoosePause = false // know when to close var intendedChoosePause = false // know when to close
@ -27,14 +26,12 @@ var action = "view"
var forApp = "" var forApp = ""
class ListActivity : AppCompatActivity() { class ListActivity : AppCompatActivity(), UIObject {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN) // TODO: Don't use actual themes, rather create them on the fly
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
setTheme( setTheme(
when (getSavedTheme(this)) { when (getSavedTheme(this)) {
"dark" -> R.style.darkTheme "dark" -> R.style.darkTheme
@ -44,40 +41,14 @@ class ListActivity : AppCompatActivity() {
) )
setContentView(R.layout.list) setContentView(R.layout.list)
if (getSavedTheme(this) == "custom") { setTheme()
list_container.setBackgroundColor(dominantColor) setOnClicks()
list_appbar.setBackgroundColor(dominantColor) configure()
list_close.setTextColor(vibrantColor) }
list_tabs.setSelectedTabIndicatorColor(vibrantColor) override fun onStart(){
} super<AppCompatActivity>.onStart()
super<UIObject>.onStart()
// As older APIs somehow do not recognize the xml defined onClick
list_close.setOnClickListener() { finish() }
// get info about which action this activity is open for
val bundle = intent.extras
if (bundle != null) {
action = bundle.getString("action")!! // why choose an app
if (action != "view")
forApp = bundle.getString("forApp")!! // which app we choose
}
// Hide tabs for the "view" action
if (action == "view") {
list_tabs.visibility = View.GONE
}
when (action) {
"view" -> list_heading.text = getString(R.string.choose_title_view)
"pick" -> list_heading.text = getString(R.string.choose_title)
}
val sectionsPagerAdapter = ListSectionsPagerAdapter(this, supportFragmentManager)
val viewPager: ViewPager = findViewById(R.id.list_viewpager)
viewPager.adapter = sectionsPagerAdapter
val tabs: TabLayout = findViewById(R.id.list_tabs)
tabs.setupWithViewPager(viewPager)
} }
override fun onPause() { override fun onPause() {
@ -104,10 +75,45 @@ class ListActivity : AppCompatActivity() {
} }
} }
/** onClick functions */ override fun setTheme() {
if (getSavedTheme(this) == "custom") {
list_container.setBackgroundColor(dominantColor)
list_appbar.setBackgroundColor(dominantColor)
list_close.setTextColor(vibrantColor)
fun backHome(view: View) { finish() } list_tabs.setSelectedTabIndicatorColor(vibrantColor)
}
}
override fun setOnClicks() {
list_close.setOnClickListener() { finish() }
}
override fun configure() {
// get info about which action this activity is open for
val bundle = intent.extras
if (bundle != null) {
action = bundle.getString("action")!! // why choose an app
if (action != "view")
forApp = bundle.getString("forApp")!! // which app we choose
}
// Hide tabs for the "view" action
if (action == "view") {
list_tabs.visibility = View.GONE
}
when (action) {
"view" -> list_heading.text = getString(R.string.choose_title_view)
"pick" -> list_heading.text = getString(R.string.choose_title)
}
val sectionsPagerAdapter = ListSectionsPagerAdapter(this, supportFragmentManager)
val viewPager: ViewPager = findViewById(R.id.list_viewpager)
viewPager.adapter = sectionsPagerAdapter
val tabs: TabLayout = findViewById(R.id.list_tabs)
tabs.setupWithViewPager(viewPager)
}
} }
private val TAB_TITLES = arrayOf( private val TAB_TITLES = arrayOf(
@ -121,8 +127,8 @@ class ListSectionsPagerAdapter(private val context: Context, fm: FragmentManager
override fun getItem(position: Int): Fragment { override fun getItem(position: Int): Fragment {
return when (position){ return when (position){
0 -> ChooseFragmentApps() 0 -> ListFragmentApps()
1 -> ChooseFragmentOther() 1 -> ListFragmentOther()
else -> Fragment() else -> Fragment()
} }
} }

View file

@ -7,6 +7,7 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment 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.list.action import com.finnmglas.launcher.list.action
import com.finnmglas.launcher.list.forApp import com.finnmglas.launcher.list.forApp
import com.finnmglas.launcher.dominantColor import com.finnmglas.launcher.dominantColor
@ -14,9 +15,9 @@ import com.finnmglas.launcher.getSavedTheme
import kotlinx.android.synthetic.main.list_apps.* import kotlinx.android.synthetic.main.list_apps.*
/** The 'Apps' Tab associated Fragment in the Chooser */ /** The 'Apps' Tab associated Fragment for the List */
class ChooseFragmentApps : Fragment() { class ListFragmentApps : Fragment(), UIObject {
/** Lifecycle functions */ /** Lifecycle functions */
@ -28,26 +29,28 @@ class ChooseFragmentApps : Fragment() {
} }
override fun onStart() { override fun onStart() {
super.onStart() super<Fragment>.onStart()
super<UIObject>.onStart()
setTheme()
configure()
}
override fun setTheme() {
if (getSavedTheme(context!!) == "custom") { if (getSavedTheme(context!!) == "custom") {
list_apps_container.setBackgroundColor(dominantColor) list_apps_container.setBackgroundColor(dominantColor)
} }
}
override fun setOnClicks() { }
override fun configure() {
// set up the list / recycler // set up the list / recycler
val viewManager = LinearLayoutManager(context)
val viewAdapter = AppsRecyclerAdapter(
activity!!,
action,
forApp
)
list_apps_rview.apply { list_apps_rview.apply {
// 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 = viewManager layoutManager = LinearLayoutManager(context)
adapter = viewAdapter adapter = AppsRecyclerAdapter(activity!!, action, forApp)
} }
} }
} }

View file

@ -13,7 +13,7 @@ import kotlinx.android.synthetic.main.list_other.*
/** The 'Other' Tab associated Fragment in the Chooser */ /** The 'Other' Tab associated Fragment in the Chooser */
class ChooseFragmentOther : Fragment() { class ListFragmentOther : Fragment() {
/** Lifecycle functions */ /** Lifecycle functions */

View file

@ -2,7 +2,6 @@ package com.finnmglas.launcher.settings
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.provider.Settings import android.provider.Settings
import android.view.View import android.view.View
@ -12,7 +11,6 @@ import androidx.viewpager.widget.ViewPager
import com.finnmglas.launcher.* import com.finnmglas.launcher.*
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import kotlinx.android.synthetic.main.settings.* import kotlinx.android.synthetic.main.settings.*
import androidx.fragment.app.Fragment 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
@ -23,13 +21,14 @@ import com.finnmglas.launcher.settings.theme.SettingsFragmentTheme
var intendedSettingsPause = false // know when to close var intendedSettingsPause = false // know when to close
class SettingsActivity : AppCompatActivity() { class SettingsActivity: AppCompatActivity(), UIObject {
/** Activity Lifecycle functions */ /** Activity Lifecycle functions */
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
// TODO: Don't use actual themes, rather create them on the fly
setTheme( setTheme(
when (getSavedTheme(this)) { when (getSavedTheme(this)) {
"dark" -> R.style.darkTheme "dark" -> R.style.darkTheme
@ -39,9 +38,8 @@ class SettingsActivity : AppCompatActivity() {
) )
setContentView(R.layout.settings) setContentView(R.layout.settings)
setTheme()
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN) setOnClicks()
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
val sectionsPagerAdapter = SettingsSectionsPagerAdapter(this, supportFragmentManager) val sectionsPagerAdapter = SettingsSectionsPagerAdapter(this, supportFragmentManager)
val viewPager: ViewPager = findViewById(R.id.settings_viewpager) val viewPager: ViewPager = findViewById(R.id.settings_viewpager)
@ -49,26 +47,11 @@ class SettingsActivity : AppCompatActivity() {
val tabs: TabLayout = findViewById(R.id.settings_tabs) val tabs: TabLayout = findViewById(R.id.settings_tabs)
tabs.setupWithViewPager(viewPager) tabs.setupWithViewPager(viewPager)
// As older APIs somehow do not recognize the xml defined onClick
settings_close.setOnClickListener() { finish() }
// open device settings (see https://stackoverflow.com/a/62092663/12787264)
settings_system.setOnClickListener {
intendedSettingsPause = true
startActivity(Intent(Settings.ACTION_SETTINGS))
}
} }
override fun onStart() { override fun onStart() {
super.onStart() super<AppCompatActivity>.onStart()
super<UIObject>.onStart()
if (getSavedTheme(this) == "custom") {
settings_container.setBackgroundColor(dominantColor)
settings_appbar.setBackgroundColor(dominantColor)
settings_system.setTextColor(vibrantColor)
settings_close.setTextColor(vibrantColor)
settings_tabs.setSelectedTabIndicatorColor(vibrantColor)
}
} }
override fun onResume() { override fun onResume() {
@ -81,28 +64,42 @@ class SettingsActivity : AppCompatActivity() {
if (!intendedSettingsPause) finish() if (!intendedSettingsPause) finish()
} }
fun backHome(view: View) { finish() }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) { when (requestCode) {
REQUEST_CHOOSE_APP -> { REQUEST_CHOOSE_APP -> {
val value = data?.getStringExtra("value") val value = data?.getStringExtra("value")
val forApp = data?.getStringExtra("forApp") ?: return val forApp = data?.getStringExtra("forApp") ?: return
// Save the new App to Preferences launcherPreferences.edit()
val sharedPref = this.getSharedPreferences( .putString("action_$forApp", value.toString())
getString(R.string.preference_file_key), Context.MODE_PRIVATE) .apply()
val editor : SharedPreferences.Editor = sharedPref.edit() loadSettings(launcherPreferences)
editor.putString("action_$forApp", value.toString())
editor.apply()
loadSettings(sharedPref)
} }
else -> super.onActivityResult(requestCode, resultCode, data) else -> super.onActivityResult(requestCode, resultCode, data)
} }
} }
override fun setTheme() {
if (getSavedTheme(this) == "custom") {
settings_container.setBackgroundColor(dominantColor)
settings_appbar.setBackgroundColor(dominantColor)
settings_system.setTextColor(vibrantColor)
settings_close.setTextColor(vibrantColor)
settings_tabs.setSelectedTabIndicatorColor(vibrantColor)
}
}
override fun setOnClicks(){
// As older APIs somehow do not recognize the xml defined onClick
settings_close.setOnClickListener() { finish() }
// open device settings (see https://stackoverflow.com/a/62092663/12787264)
settings_system.setOnClickListener {
intendedSettingsPause = true
startActivity(Intent(Settings.ACTION_SETTINGS))
}
}
} }
private val TAB_TITLES = arrayOf( private val TAB_TITLES = arrayOf(

View file

@ -3,7 +3,6 @@ package com.finnmglas.launcher.settings.actions
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -31,7 +30,6 @@ class ActionsRecyclerAdapter(val activity: Activity):
var chooseButton: Button = itemView.findViewById(R.id.settings_actions_row_button_choose) var chooseButton: Button = itemView.findViewById(R.id.settings_actions_row_button_choose)
var removeAction: FontAwesome = itemView.findViewById(R.id.settings_actions_row_remove) var removeAction: FontAwesome = itemView.findViewById(R.id.settings_actions_row_remove)
override fun onClick(v: View) { override fun onClick(v: View) {
val pos = adapterPosition val pos = adapterPosition
val context: Context = v.context val context: Context = v.context
@ -50,10 +48,8 @@ class ActionsRecyclerAdapter(val activity: Activity):
viewHolder.textView.text = actionText viewHolder.textView.text = actionText
viewHolder.removeAction.setOnClickListener{ viewHolder.removeAction.setOnClickListener{
val sharedPref = activity.getSharedPreferences(
activity.getString(R.string.preference_file_key), Context.MODE_PRIVATE)
val editor : SharedPreferences.Editor = sharedPref.edit() val editor = launcherPreferences.edit()
editor.putString("action_$actionName", "") // clear it editor.putString("action_$actionName", "") // clear it
editor.apply() editor.apply()

View file

@ -18,7 +18,7 @@ import kotlinx.android.synthetic.main.settings_actions.*
/** The 'Apps' Tab associated Fragment in Settings */ /** The 'Apps' Tab associated Fragment in Settings */
class SettingsFragmentActions : Fragment() { class SettingsFragmentActions : Fragment(), UIObject {
/** Lifecycle functions */ /** Lifecycle functions */
@ -30,7 +30,25 @@ class SettingsFragmentActions : Fragment() {
} }
override fun onStart() { override fun onStart() {
super<Fragment>.onStart()
super<UIObject>.onStart()
setTheme()
setOnClicks()
// set up the list / recycler
val actionViewManager = LinearLayoutManager(context)
val actionViewAdapter = ActionsRecyclerAdapter( activity!! )
settings_actions_rview.apply {
// improve performance (since content changes don't change the layout size)
setHasFixedSize(true)
layoutManager = actionViewManager
adapter = actionViewAdapter
}
}
override fun setTheme() {
if (getSavedTheme(context!!) == "custom") { if (getSavedTheme(context!!) == "custom") {
settings_actions_container.setBackgroundColor(dominantColor) settings_actions_container.setBackgroundColor(dominantColor)
@ -43,18 +61,9 @@ class SettingsFragmentActions : Fragment() {
vibrantColor vibrantColor
) )
} }
}
override fun setOnClicks() {
// set up the list / recycler
val actionViewManager = LinearLayoutManager(context)
val actionViewAdapter = ActionsRecyclerAdapter( activity!! )
settings_actions_rview.apply {
// improve performance (since content changes don't change the layout size)
setHasFixedSize(true)
layoutManager = actionViewManager
adapter = actionViewAdapter
}
// App management buttons // App management buttons
settings_actions_button_view_apps.setOnClickListener{ settings_actions_button_view_apps.setOnClickListener{
@ -75,7 +84,5 @@ class SettingsFragmentActions : Fragment() {
.show() .show()
} }
} }
super.onStart()
} }
} }

View file

@ -2,7 +2,6 @@ package com.finnmglas.launcher.settings.meta
import android.app.AlertDialog import android.app.AlertDialog
import android.content.ActivityNotFoundException import android.content.ActivityNotFoundException
import android.content.Context
import android.content.DialogInterface import android.content.DialogInterface
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
@ -20,7 +19,7 @@ import kotlinx.android.synthetic.main.settings_meta.*
/** The 'Meta' Tab associated Fragment in Settings */ /** The 'Meta' Tab associated Fragment in Settings */
class SettingsFragmentMeta : Fragment() { class SettingsFragmentMeta : Fragment(), UIObject {
/** Lifecycle functions */ /** Lifecycle functions */
@ -32,35 +31,52 @@ class SettingsFragmentMeta : Fragment() {
} }
override fun onStart() { override fun onStart() {
super<Fragment>.onStart()
super<UIObject>.onStart()
setTheme()
setOnClicks()
}
/** Extra functions */
// Rate App
// Just copied code from https://stackoverflow.com/q/10816757/12787264
// that is how we write good software ^^
private fun rateIntentForUrl(url: String): Intent {
val intent = Intent(
Intent.ACTION_VIEW,
Uri.parse(String.format("%s?id=%s", url, this.context!!.packageName))
)
var flags = Intent.FLAG_ACTIVITY_NO_HISTORY or Intent.FLAG_ACTIVITY_MULTIPLE_TASK
flags = if (Build.VERSION.SDK_INT >= 21) {
flags or Intent.FLAG_ACTIVITY_NEW_DOCUMENT
} else {
flags or Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
}
intent.addFlags(flags)
return intent
}
override fun setTheme() {
if (getSavedTheme(context!!) == "custom") { if (getSavedTheme(context!!) == "custom") {
settings_meta_container.setBackgroundColor(dominantColor) settings_meta_container.setBackgroundColor(dominantColor)
setButtonColor( setButtonColor(settings_meta_button_select_launcher, vibrantColor)
settings_meta_button_select_launcher, setButtonColor(settings_meta_button_view_tutorial, vibrantColor)
vibrantColor setButtonColor(settings_meta_button_reset_settings, vibrantColor)
) setButtonColor(settings_meta_button_contact, vibrantColor)
setButtonColor( setButtonColor(settings_meta_button_donate, vibrantColor)
settings_meta_button_view_tutorial,
vibrantColor
)
setButtonColor(
settings_meta_button_reset_settings,
vibrantColor
)
setButtonColor(
settings_meta_button_contact,
vibrantColor
)
setButtonColor(
settings_meta_button_donate,
vibrantColor
)
settings_meta_icon_google_play.setTextColor(vibrantColor) settings_meta_icon_google_play.setTextColor(vibrantColor)
settings_meta_icon_github.setTextColor(vibrantColor) settings_meta_icon_github.setTextColor(vibrantColor)
settings_meta_icon_globe.setTextColor(vibrantColor) settings_meta_icon_globe.setTextColor(vibrantColor)
} }
}
override fun setOnClicks() {
// Button onClicks // Button onClicks
@ -106,12 +122,7 @@ class SettingsFragmentMeta : Fragment() {
.setMessage(getString(R.string.settings_reset_message)) .setMessage(getString(R.string.settings_reset_message))
.setPositiveButton(android.R.string.yes, .setPositiveButton(android.R.string.yes,
DialogInterface.OnClickListener { _, _ -> DialogInterface.OnClickListener { _, _ ->
resetSettings( resetSettings(launcherPreferences, this.context!!)
this.context!!.getSharedPreferences(
getString(R.string.preference_file_key),
Context.MODE_PRIVATE
), this.context!!
)
activity!!.finish() activity!!.finish()
}) })
.setNegativeButton(android.R.string.no, null) .setNegativeButton(android.R.string.no, null)
@ -165,28 +176,5 @@ class SettingsFragmentMeta : Fragment() {
context!! context!!
) )
} }
super.onStart()
}
/** Extra functions */
// Rate App
// Just copied code from https://stackoverflow.com/q/10816757/12787264
// that is how we write good software ^^
private fun rateIntentForUrl(url: String): Intent {
val intent = Intent(
Intent.ACTION_VIEW,
Uri.parse(String.format("%s?id=%s", url, this.context!!.packageName))
)
var flags = Intent.FLAG_ACTIVITY_NO_HISTORY or Intent.FLAG_ACTIVITY_MULTIPLE_TASK
flags = if (Build.VERSION.SDK_INT >= 21) {
flags or Intent.FLAG_ACTIVITY_NEW_DOCUMENT
} else {
flags or Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
}
intent.addFlags(flags)
return intent
} }
} }

View file

@ -22,10 +22,9 @@ import kotlinx.android.synthetic.main.settings_theme.*
/** The 'Theme' Tab associated Fragment in Settings */ /** The 'Theme' Tab associated Fragment in Settings */
class SettingsFragmentTheme : Fragment() { class SettingsFragmentTheme : Fragment(), UIObject {
/** Lifecycle functions */ /** Lifecycle functions */
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
@ -34,71 +33,11 @@ class SettingsFragmentTheme : Fragment() {
} }
override fun onStart(){ override fun onStart(){
// Hide 'select' button for the selected theme or allow customisation super<Fragment>.onStart()
when (getSavedTheme(context!!)) { super<UIObject>.onStart()
"dark" -> settings_theme_dark_button_select.visibility = View.INVISIBLE
"finn" -> settings_theme_finn_button_select.visibility = View.INVISIBLE
"custom" -> {
settings_theme_custom_button_select.text = getString(R.string.settings_select_image)
settings_theme_container.setBackgroundColor(dominantColor)
setButtonColor(
settings_theme_finn_button_select,
vibrantColor
)
setButtonColor(
settings_theme_dark_button_select,
vibrantColor
)
setButtonColor(
settings_theme_custom_button_select,
vibrantColor
)
setButtonColor(
settings_theme_custom_button_examples,
vibrantColor
)
}
}
// Theme changing buttons setTheme()
settings_theme_dark_button_select.setOnClickListener { setOnClicks()
intendedSettingsPause = true
saveTheme(context!!, "dark")
activity!!.recreate()
}
settings_theme_finn_button_select.setOnClickListener {
intendedSettingsPause = true
saveTheme(context!!, "finn")
activity!!.recreate()
}
settings_theme_custom_button_select.setOnClickListener {
intendedSettingsPause = true
// Request permission (on newer APIs)
if (Build.VERSION.SDK_INT >= 23) {
when {
ContextCompat.checkSelfPermission(context!!,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
-> letUserPickImage(true)
shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)
-> {}
else
-> requestPermissions(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
REQUEST_PERMISSION_STORAGE
)
}
}
else letUserPickImage()
}
settings_theme_custom_button_examples.setOnClickListener {
intendedSettingsPause = true
// Show example usage
openNewTabWindow(
"https://github.com/finnmglas/Launcher/blob/master/docs/README.md",
context!!
)
}
super.onStart()
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
@ -130,7 +69,6 @@ class SettingsFragmentTheme : Fragment() {
} }
private fun handlePickedImage(resultCode: Int, data: Intent?) { private fun handlePickedImage(resultCode: Int, data: Intent?) {
if (resultCode == AppCompatActivity.RESULT_OK) { if (resultCode == AppCompatActivity.RESULT_OK) {
if (data == null) return if (data == null) return
@ -175,4 +113,72 @@ class SettingsFragmentTheme : Fragment() {
} }
} }
} }
override fun setTheme() {
// Hide 'select' button for the selected theme or allow customisation
when (getSavedTheme(context!!)) {
"dark" -> settings_theme_dark_button_select.visibility = View.INVISIBLE
"finn" -> settings_theme_finn_button_select.visibility = View.INVISIBLE
"custom" -> {
settings_theme_custom_button_select.text = getString(R.string.settings_select_image)
settings_theme_container.setBackgroundColor(dominantColor)
setButtonColor(
settings_theme_finn_button_select,
vibrantColor
)
setButtonColor(
settings_theme_dark_button_select,
vibrantColor
)
setButtonColor(
settings_theme_custom_button_select,
vibrantColor
)
setButtonColor(
settings_theme_custom_button_examples,
vibrantColor
)
}
}
}
override fun setOnClicks() {
// Theme changing buttons
settings_theme_dark_button_select.setOnClickListener {
intendedSettingsPause = true
saveTheme(context!!, "dark")
activity!!.recreate()
}
settings_theme_finn_button_select.setOnClickListener {
intendedSettingsPause = true
saveTheme(context!!, "finn")
activity!!.recreate()
}
settings_theme_custom_button_select.setOnClickListener {
intendedSettingsPause = true
// Request permission (on newer APIs)
if (Build.VERSION.SDK_INT >= 23) {
when {
ContextCompat.checkSelfPermission(context!!,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
-> letUserPickImage(true)
shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)
-> {}
else
-> requestPermissions(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
REQUEST_PERMISSION_STORAGE
)
}
}
else letUserPickImage()
}
settings_theme_custom_button_examples.setOnClickListener {
intendedSettingsPause = true
// Show example usage
openNewTabWindow(
"https://github.com/finnmglas/Launcher/blob/master/docs/README.md",
context!!
)
}
}
} }

View file

@ -1,7 +1,6 @@
package com.finnmglas.launcher.tutorial package com.finnmglas.launcher.tutorial
import android.content.Context import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.util.TypedValue import android.util.TypedValue
import android.view.* import android.view.*
@ -10,7 +9,7 @@ import com.finnmglas.launcher.*
import kotlinx.android.synthetic.main.tutorial.* import kotlinx.android.synthetic.main.tutorial.*
class TutorialActivity : AppCompatActivity(){ class TutorialActivity : AppCompatActivity(), UIObject{
/** Variables for this activity */ /** Variables for this activity */
@ -23,13 +22,7 @@ class TutorialActivity : AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
// Flags // TODO: Don't use actual themes, rather create them on the fly
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
)
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
setTheme( setTheme(
when (getSavedTheme(this)) { when (getSavedTheme(this)) {
"dark" -> R.style.darkTheme "dark" -> R.style.darkTheme
@ -37,35 +30,31 @@ class TutorialActivity : AppCompatActivity(){
else -> R.style.finnmglasTheme else -> R.style.finnmglasTheme
} }
) )
setContentView(R.layout.tutorial) setContentView(R.layout.tutorial)
setTheme()
setOnClicks()
if (getSavedTheme(this) == "custom") {
tutorial_appbar.setBackgroundColor(dominantColor)
tutorial_container.setBackgroundColor(dominantColor)
tutorial_close.setTextColor(vibrantColor)
}
tutorial_page_hint.blink() // animate
loadMenu(this) loadMenu(this)
val sharedPref = this.getSharedPreferences(getString(R.string.preference_file_key), Context.MODE_PRIVATE) isFirstTime = !launcherPreferences.getBoolean("startedBefore", false)
isFirstTime = !sharedPref.getBoolean("startedBefore", false)
if (isFirstTime) if (isFirstTime)
defaultApps = resetSettings( defaultApps = resetSettings(
sharedPref, launcherPreferences,
this this
) // UP, DOWN, RIGHT, LEFT, VOLUME_UP, VOLUME_DOWN ) // UP, DOWN, RIGHT, LEFT, VOLUME_UP, VOLUME_DOWN
else else
tutorial_appbar.visibility = View.VISIBLE tutorial_appbar.visibility = View.VISIBLE
}
// As older APIs somehow do not recognize the xml defined onClick override fun onStart() {
tutorial_close.setOnClickListener() { finish() } super<AppCompatActivity>.onStart()
super<UIObject>.onStart()
} }
/** Touch- and Key-related functions to navigate */ /** Touch- and Key-related functions to navigate */
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP){ if (keyCode == KeyEvent.KEYCODE_VOLUME_UP){
menuNumber++ menuNumber++
@ -87,14 +76,7 @@ class TutorialActivity : AppCompatActivity(){
loadMenu(this) loadMenu(this)
} }
fun backToSettings(view: View){ private fun loadMenu(context: Context) { // Context needed for packageManager
finish()
}
/** Touch- and Key-related functions to navigate */
private fun loadMenu(context :Context) { // Context needed for packageManager
val intro = resources.getStringArray(R.array.intro) val intro = resources.getStringArray(R.array.intro)
if (menuNumber < intro.size){ if (menuNumber < intro.size){
@ -113,14 +95,26 @@ class TutorialActivity : AppCompatActivity(){
} else { // End intro } else { // End intro
if (isFirstTime){ if (isFirstTime){
val sharedPref = this.getSharedPreferences(getString(R.string.preference_file_key), Context.MODE_PRIVATE) launcherPreferences.edit()
.putBoolean("startedBefore", true) // never auto run this again
val editor: SharedPreferences.Editor = sharedPref.edit() .putLong("firstStartup", System.currentTimeMillis() / 1000L) // record first startup timestamp
editor.putBoolean("startedBefore", true) // never auto run this again .apply()
editor.putLong("firstStartup", System.currentTimeMillis() / 1000L) // record first startup timestamp
editor.apply()
} }
finish() finish()
} }
} }
override fun setTheme() {
if (getSavedTheme(this) == "custom") {
tutorial_appbar.setBackgroundColor(dominantColor)
tutorial_container.setBackgroundColor(dominantColor)
tutorial_close.setTextColor(vibrantColor)
}
tutorial_page_hint.blink() // animate
}
override fun setOnClicks() {
tutorial_close.setOnClickListener() { finish() }
}
} }

View file

@ -25,7 +25,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="start|center_vertical" android:gravity="start|center_vertical"
android:onClick="dateViewOnTouch"
android:textSize="30sp" android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
@ -38,7 +37,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="start|center_vertical" android:gravity="start|center_vertical"
android:onClick="timeViewOnTouch"
android:textSize="18sp" android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
@ -50,7 +48,6 @@
android:id="@+id/home_settings_icon" android:id="@+id/home_settings_icon"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:onClick="settingsIconOnTouch"
android:text="@string/fas_settings" android:text="@string/fas_settings"
android:textColor="?attr/colorAccent" android:textColor="?attr/colorAccent"
android:textSize="36sp" android:textSize="36sp"

View file

@ -45,7 +45,6 @@
android:layout_marginRight="8dp" android:layout_marginRight="8dp"
android:gravity="center" android:gravity="center"
android:includeFontPadding="true" android:includeFontPadding="true"
android:onClick="backHome"
android:paddingLeft="16sp" android:paddingLeft="16sp"
android:paddingRight="16sp" android:paddingRight="16sp"
android:text="@string/fa_close_window" android:text="@string/fa_close_window"

View file

@ -37,11 +37,9 @@
android:id="@+id/settings_close" android:id="@+id/settings_close"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp" android:layout_marginRight="8dp"
android:gravity="center" android:gravity="center"
android:includeFontPadding="true" android:includeFontPadding="true"
android:onClick="backHome"
android:paddingLeft="16sp" android:paddingLeft="16sp"
android:paddingRight="16sp" android:paddingRight="16sp"
android:text="@string/fa_close_window" android:text="@string/fa_close_window"

View file

@ -46,7 +46,6 @@
android:layout_marginRight="8dp" android:layout_marginRight="8dp"
android:gravity="center" android:gravity="center"
android:includeFontPadding="true" android:includeFontPadding="true"
android:onClick="backToSettings"
android:paddingLeft="16sp" android:paddingLeft="16sp"
android:paddingRight="16sp" android:paddingRight="16sp"
android:text="@string/fa_close_window" android:text="@string/fa_close_window"