Merge pull request #53 from finnmglas/fix/code

Fix/code
This commit is contained in:
Finn M Glas 2020-06-19 10:35:13 +02:00 committed by GitHub
commit a8303c256c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 1124 additions and 1009 deletions

View file

@ -14,7 +14,7 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/finnmglasTheme"> android:theme="@style/finnmglasTheme">
<activity android:name=".MainActivity" <activity android:name=".HomeActivity"
android:screenOrientation="portrait" android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity"> tools:ignore="LockedOrientationActivity">
<intent-filter> <intent-filter>
@ -28,7 +28,7 @@
android:screenOrientation="portrait" android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity"> tools:ignore="LockedOrientationActivity">
</activity> </activity>
<activity android:name=".choose.ChooseActivity" <activity android:name=".list.ListActivity"
android:screenOrientation="portrait" android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity"> tools:ignore="LockedOrientationActivity">
</activity> </activity>

View file

@ -1,4 +1,4 @@
package com.finnmglas.launcher.extern package com.finnmglas.launcher
import android.app.Activity import android.app.Activity
import android.app.AlertDialog import android.app.AlertDialog
@ -12,19 +12,28 @@ import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.provider.Settings import android.provider.Settings
import android.util.DisplayMetrics
import android.view.View import android.view.View
import android.view.animation.* import android.view.animation.*
import android.widget.Button import android.widget.Button
import android.widget.ImageView import android.widget.ImageView
import android.widget.Toast import android.widget.Toast
import com.finnmglas.launcher.choose.ChooseActivity import com.finnmglas.launcher.list.ListActivity
import com.finnmglas.launcher.R 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 kotlin.math.roundToInt import kotlin.math.roundToInt
/* Preferences (global, initialised when app is started) */
lateinit var launcherPreferences: SharedPreferences
/* Objects used by multiple activities */
lateinit var appListViewAdapter: AppsRecyclerAdapter
/* Variables containing settings */
val displayMetrics = DisplayMetrics()
/** Variables for all of the app */
var upApp = "" var upApp = ""
var downApp = "" var downApp = ""
var rightApp = "" var rightApp = ""
@ -42,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(
@ -120,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 {
@ -137,15 +146,18 @@ private fun getIntent(packageName: String, context: Context): Intent? {
return intent return intent
} }
// select what to launch fun launch(data: String, activity: Activity,
fun launch(data: String, activity: Activity) { animationIn: Int = android.R.anim.fade_in, animationOut: Int = android.R.anim.fade_out) {
if (data.startsWith("launcher:")) // [type]:[info] if (data.startsWith("launcher:")) // [type]:[info]
when(data.split(":")[1]) { when(data.split(":")[1]) {
"settings" -> openSettings(activity) "settings" -> openSettings(activity)
"choose" -> openAppsList(activity) "choose" -> openAppsList(activity)
"tutorial" -> openTutorial(activity)
} }
else launchApp(data, activity) // app else launchApp(data, activity) // app
activity.overridePendingTransition(animationIn, animationOut)
} }
fun launchApp(packageName: String, context: Context) { fun launchApp(packageName: String, context: Context) {
@ -186,22 +198,16 @@ 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 {
val sharedPref = context.getSharedPreferences( return launcherPreferences.getString("theme", "finn").toString()
context.getString(R.string.preference_file_key), Context.MODE_PRIVATE)
return sharedPref.getString("theme", "finn").toString()
} }
fun saveTheme(context : Context, themeName : String) : String { fun saveTheme(themeName : String) : String {
val sharedPref = context.getSharedPreferences( launcherPreferences.edit()
context.getString(R.string.preference_file_key), Context.MODE_PRIVATE) .putString("theme", themeName)
.apply()
val editor: SharedPreferences.Editor = sharedPref.edit()
editor.putString("theme", themeName)
editor.apply()
return themeName return themeName
} }
@ -216,39 +222,43 @@ fun openSettings(activity: Activity){
activity.startActivity(Intent(activity, SettingsActivity::class.java)) activity.startActivity(Intent(activity, SettingsActivity::class.java))
} }
fun openTutorial(activity: Activity){
activity.startActivity(Intent(activity, TutorialActivity::class.java))
}
fun openAppsList(activity: Activity){ fun openAppsList(activity: Activity){
val intent = Intent(activity, ChooseActivity::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)
} }
fun loadSettings(sharedPref : SharedPreferences){ fun loadSettings(){
upApp = sharedPref.getString("action_upApp", "").toString() upApp = launcherPreferences.getString("action_upApp", "").toString()
downApp = sharedPref.getString("action_downApp", "").toString() downApp = launcherPreferences.getString("action_downApp", "").toString()
rightApp = sharedPref.getString("action_rightApp", "").toString() rightApp = launcherPreferences.getString("action_rightApp", "").toString()
leftApp = sharedPref.getString("action_leftApp", "").toString() leftApp = launcherPreferences.getString("action_leftApp", "").toString()
volumeUpApp = sharedPref.getString("action_volumeUpApp", "").toString() volumeUpApp = launcherPreferences.getString("action_volumeUpApp", "").toString()
volumeDownApp = sharedPref.getString("action_volumeDownApp", "").toString() volumeDownApp = launcherPreferences.getString("action_volumeDownApp", "").toString()
doubleClickApp = sharedPref.getString("action_doubleClickApp", "").toString() doubleClickApp = launcherPreferences.getString("action_doubleClickApp", "").toString()
longClickApp = sharedPref.getString("action_longClickApp", "").toString() longClickApp = launcherPreferences.getString("action_longClickApp", "").toString()
calendarApp = sharedPref.getString("action_calendarApp", "").toString() calendarApp = launcherPreferences.getString("action_calendarApp", "").toString()
clockApp = sharedPref.getString("action_clockApp", "").toString() clockApp = launcherPreferences.getString("action_clockApp", "").toString()
dominantColor = sharedPref.getInt("custom_dominant", 0) dominantColor = launcherPreferences.getInt("custom_dominant", 0)
vibrantColor = sharedPref.getInt("custom_vibrant", 0) vibrantColor = launcherPreferences.getInt("custom_vibrant", 0)
} }
fun resetSettings(sharedPref : SharedPreferences, context: Context) : MutableList<String>{ fun resetSettings(context: Context) : MutableList<String>{
// set default theme // set default theme
saveTheme(context, "finn") saveTheme("finn")
val defaultList :MutableList<String> = mutableListOf<String>() val defaultList :MutableList<String> = mutableListOf<String>()
val editor: SharedPreferences.Editor = sharedPref.edit() val editor = launcherPreferences.edit()
val (chosenUpName, chosenUpPackage) = pickDefaultApp( val (chosenUpName, chosenUpPackage) = pickDefaultApp(
"action_upApp", "action_upApp",
@ -331,14 +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 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)

View file

@ -6,136 +6,93 @@ import android.net.Uri
import android.os.AsyncTask import android.os.AsyncTask
import android.os.Bundle import android.os.Bundle
import android.provider.MediaStore import android.provider.MediaStore
import android.util.DisplayMetrics
import android.view.* import android.view.*
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GestureDetectorCompat import androidx.core.view.GestureDetectorCompat
import androidx.recyclerview.widget.RecyclerView import com.finnmglas.launcher.list.apps.AppsRecyclerAdapter
import com.finnmglas.launcher.choose.apps.AppsRecyclerAdapter
import com.finnmglas.launcher.extern.*
import com.finnmglas.launcher.tutorial.TutorialActivity import com.finnmglas.launcher.tutorial.TutorialActivity
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.home.*
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
import kotlin.concurrent.fixedRateTimer import kotlin.concurrent.fixedRateTimer
import kotlin.math.abs import kotlin.math.abs
// used for the apps drawer / menu (ChooseActivity) /**
lateinit var viewAdapter: RecyclerView.Adapter<*> * [HomeActivity] is the actual application Launcher,
lateinit var viewManager: RecyclerView.LayoutManager * what makes this application special / unique.
*
class MainActivity : AppCompatActivity(), * 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(),
GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener { GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener {
private var currentTheme = "" // keep track of theme changes
/** Variables for this activity */
private lateinit var mDetector: GestureDetectorCompat private lateinit var mDetector: GestureDetectorCompat
// get device dimensions
private val displayMetrics = DisplayMetrics()
// timers // timers
private var clockTimer = Timer() private var clockTimer = Timer()
private var tooltipTimer = Timer() private var tooltipTimer = Timer()
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)
// Preferences // Initialise globals
val sharedPref = this.getSharedPreferences( launcherPreferences = this.getSharedPreferences(
getString(R.string.preference_file_key), Context.MODE_PRIVATE) getString(R.string.preference_file_key), Context.MODE_PRIVATE)
// Flags windowManager.defaultDisplay.getMetrics(displayMetrics)
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
)
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
currentTheme = getSavedTheme(this) loadSettings()
if (currentTheme == "custom") { // Preload list of apps (speed up loading time)
try { AsyncTask.execute {
background = MediaStore.Images.Media.getBitmap(this.contentResolver, Uri.parse(sharedPref.getString("background_uri", ""))) appListViewAdapter = AppsRecyclerAdapter(this)
} catch (e: Exception) { }
if (background == null)
currentTheme = saveTheme(this, "finn")
} }
setTheme( // First time opening the app: show Tutorial
when (currentTheme) { if (!launcherPreferences.getBoolean("startedBefore", false))
"dark" -> R.style.darkTheme
"finn" -> R.style.finnmglasTheme
else -> R.style.customTheme
}
)
setContentView(R.layout.activity_main)
// Start by showing the settings icon
showSettingsIcon()
// As older APIs somehow do not recognize the xml defined onClick
activity_main_settings_icon.setOnClickListener() {
openSettings(this)
overridePendingTransition(R.anim.bottom_up, android.R.anim.fade_out)
}
// Load apps list first - speed up settings that way
AsyncTask.execute { viewAdapter =
AppsRecyclerAdapter(this, "", "")
}
// First Startup
if (!sharedPref.getBoolean("startedBefore", false)){
startActivity(Intent(this, TutorialActivity::class.java)) startActivity(Intent(this, TutorialActivity::class.java))
tooltipTimer.cancel()
} // Initialise layout
setContentView(R.layout.home)
} }
override fun onStart(){ override fun onStart(){
super.onStart() super<AppCompatActivity>.onStart()
// Preferences
val sharedPref = this.getSharedPreferences(
getString(R.string.preference_file_key), Context.MODE_PRIVATE)
loadSettings(sharedPref)
if (currentTheme == "custom") {
activity_main_settings_icon.setTextColor(vibrantColor)
}
mDetector = GestureDetectorCompat(this, this) mDetector = GestureDetectorCompat(this, this)
mDetector.setOnDoubleTapListener(this) mDetector.setOnDoubleTapListener(this)
windowManager.defaultDisplay.getMetrics(displayMetrics) // for if the settings changed
loadSettings()
super<UIObject>.onStart()
} }
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
// TODO: do this immediately after changing preferences if (home_background_image != null && getSavedTheme(this) == "custom")
if (currentTheme != getSavedTheme(this)) recreate() home_background_image.setImageBitmap(background)
if (activity_main_background_image != null && getSavedTheme(this) == "custom")
activity_main_background_image.setImageBitmap(background)
val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()) val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
val timeFormat = SimpleDateFormat("HH:mm:ss", Locale.getDefault()) val timeFormat = SimpleDateFormat("HH:mm:ss", Locale.getDefault())
clockTimer = fixedRateTimer("clockTimer", true, 0L, 100) { clockTimer = fixedRateTimer("clockTimer", true, 0L, 100) {
this@MainActivity.runOnUiThread { this@HomeActivity.runOnUiThread {
val t = timeFormat.format(Date()) val t = timeFormat.format(Date())
if (activity_main_time_view.text != t) if (home_time_view.text != t)
activity_main_time_view.text = t home_time_view.text = t
val d = dateFormat.format(Date()) val d = dateFormat.format(Date())
if (activity_main_date_view.text != d) if (home_date_view.text != d)
activity_main_date_view.text = d home_date_view.text = d
} }
} }
} }
@ -143,20 +100,19 @@ class MainActivity : AppCompatActivity(),
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
clockTimer.cancel() clockTimer.cancel()
}
/** Touch- and Key-related functions to start activities */ hideSettingsIcon()
}
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) launch(volumeUpApp, this) else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP)
else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) launch(volumeDownApp, this) launch(volumeUpApp, this,0, 0)
else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)
launch(volumeDownApp, this,0, 0)
return true return true
} }
fun dateViewOnTouch(v: View) { launch(calendarApp, this) }
fun timeViewOnTouch(v: View) { launch(clockApp, this) }
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
@ -168,24 +124,26 @@ class MainActivity : AppCompatActivity(),
val strictness = 4 // how distinguished the swipe has to be to be accepted val strictness = 4 // how distinguished the swipe has to be to be accepted
// Only open if the swipe was not from the phones top edge // Only open if the swipe was not from the phones top edge
if (diffY < -height / 8 && abs(diffY) > strictness * abs(diffX) && e1.y > 100) launch(downApp, this) if (diffY < -height / 8 && abs(diffY) > strictness * abs(diffX) && e1.y > 100)
else if (diffY > height / 8 && abs(diffY) > strictness * abs(diffX)) { launch(downApp,this, R.anim.top_down)
launch(upApp, this) else if (diffY > height / 8 && abs(diffY) > strictness * abs(diffX))
overridePendingTransition(R.anim.bottom_up, android.R.anim.fade_out) launch(upApp, this, R.anim.bottom_up)
} else if (diffX > width / 4 && abs(diffX) > strictness * abs(diffY))
else if (diffX > width / 4 && abs(diffX) > strictness * abs(diffY)) launch(leftApp, this) launch(leftApp,this, R.anim.right_left)
else if (diffX < -width / 4 && abs(diffX) > strictness * abs(diffY)) launch(rightApp, this) else if (diffX < -width / 4 && abs(diffX) > strictness * abs(diffY))
launch(rightApp, this, R.anim.left_right)
return true return true
} }
override fun onLongPress(event: MotionEvent) { override fun onLongPress(event: MotionEvent) {
if(longClickApp != "") launch(longClickApp, this) launch(longClickApp, this)
else openSettings(this) overridePendingTransition(0, 0)
} }
override fun onDoubleTap(event: MotionEvent): Boolean { override fun onDoubleTap(event: MotionEvent): Boolean {
launch(doubleClickApp, this) launch(doubleClickApp, this)
overridePendingTransition(0, 0)
return false return false
} }
@ -201,28 +159,75 @@ class MainActivity : AppCompatActivity(),
} }
private fun showSettingsIcon(){ private fun showSettingsIcon(){
activity_main_settings_icon.fadeRotateIn() home_settings_icon.fadeRotateIn()
activity_main_settings_icon.visibility = View.VISIBLE home_settings_icon.visibility = View.VISIBLE
settingsIconShown = true settingsIconShown = true
tooltipTimer = fixedRateTimer("tooltipTimer", true, 10000, 1000) { tooltipTimer = fixedRateTimer("tooltipTimer", true, 10000, 1000) {
this@MainActivity.runOnUiThread { hideSettingsIcon() } this@HomeActivity.runOnUiThread { hideSettingsIcon() }
} }
} }
private fun hideSettingsIcon(){ private fun hideSettingsIcon(){
tooltipTimer.cancel() tooltipTimer.cancel()
activity_main_settings_icon.fadeRotateOut() home_settings_icon.fadeRotateOut()
activity_main_settings_icon.visibility = View.INVISIBLE home_settings_icon.visibility = View.INVISIBLE
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 applyTheme() {
// Start by showing the settings icon
showSettingsIcon()
home_settings_icon.setTextColor(vibrantColor)
home_container.setBackgroundColor(dominantColor)
if (launcherPreferences.getString("background_uri", "") != "") {
try {
background = MediaStore.Images.Media.getBitmap(
this.contentResolver, Uri.parse(
launcherPreferences.getString("background_uri", "")
)
)
} catch (e: Exception) { }
if (background == null) { // same as in Settings - TODO make function called by both
dominantColor = resources.getColor(R.color.finnmglasTheme_background_color)
vibrantColor = resources.getColor(R.color.finnmglasTheme_accent_color)
launcherPreferences.edit()
.putString("background_uri", "")
.putInt("custom_dominant", dominantColor)
.putInt("custom_vibrant", vibrantColor)
.apply()
saveTheme("finn")
recreate()
}
home_background_image.visibility = View.VISIBLE
} else {
home_background_image.visibility = View.INVISIBLE
}
}
override fun setOnClicks() {
home_settings_icon.setOnClickListener() {
launch("launcher:settings", this, R.anim.bottom_up)
}
home_date_view.setOnClickListener() {
launch(calendarApp, this)
}
home_time_view.setOnClickListener() {
launch(clockApp,this)
}
}
/* 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,27 @@
package com.finnmglas.launcher
import android.app.Activity
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 {
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)
}
applyTheme()
setOnClicks()
adjustLayout()
}
// Don't use actual themes, rather create them on the fly for faster theme-switching
fun applyTheme() { }
fun setOnClicks() { }
fun adjustLayout() { }
}

View file

@ -1,103 +0,0 @@
package com.finnmglas.launcher.choose
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.view.WindowManager
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.viewpager.widget.ViewPager
import com.finnmglas.launcher.R
import com.finnmglas.launcher.extern.*
import com.finnmglas.launcher.settings.intendedSettingsPause
import com.google.android.material.tabs.TabLayout
import kotlinx.android.synthetic.main.activity_choose.*
var intendedChoosePause = false // know when to close
// TODO: Better solution for this (used in choose-fragments)
var action = "view"
var forApp = ""
class ChooseActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
setTheme(
when (getSavedTheme(this)) {
"dark" -> R.style.darkTheme
"finn" -> R.style.finnmglasTheme
else -> R.style.finnmglasTheme
}
)
setContentView(R.layout.activity_choose)
if (getSavedTheme(this) == "custom") {
activity_choose_container.setBackgroundColor(dominantColor)
activity_choose_app_bar.setBackgroundColor(dominantColor)
activity_choose_close.setTextColor(vibrantColor)
}
// As older APIs somehow do not recognize the xml defined onClick
activity_choose_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") {
activity_choose_tabs.visibility = View.GONE
}
when (action) {
"view" -> activity_choose_heading.text = getString(R.string.choose_title_view)
"pick" -> activity_choose_heading.text = getString(R.string.choose_title)
}
val sectionsPagerAdapter = ChooseSectionsPagerAdapter(this, supportFragmentManager)
val viewPager: ViewPager = findViewById(R.id.activity_choose_view_pager)
viewPager.adapter = sectionsPagerAdapter
val tabs: TabLayout = findViewById(R.id.activity_choose_tabs)
tabs.setupWithViewPager(viewPager)
}
override fun onPause() {
super.onPause()
intendedSettingsPause = false
if(!intendedChoosePause) finish()
}
override fun onResume() {
super.onResume()
intendedChoosePause = false
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_UNINSTALL) {
if (resultCode == Activity.RESULT_OK) {
Toast.makeText(this, getString(R.string.choose_removed_toast), Toast.LENGTH_LONG).show()
finish()
} else if (resultCode == Activity.RESULT_FIRST_USER) {
Toast.makeText(this, getString(R.string.choose_not_removed_toast), Toast.LENGTH_LONG).show()
finish()
}
}
}
/** onClick functions */
fun backHome(view: View) { finish() }
}

View file

@ -1,38 +0,0 @@
package com.finnmglas.launcher.choose
import android.content.Context
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
import com.finnmglas.launcher.*
import com.finnmglas.launcher.choose.apps.ChooseFragmentApps
import com.finnmglas.launcher.choose.other.ChooseFragmentOther
private val TAB_TITLES = arrayOf(
R.string.choose_tab_app,
R.string.choose_tab_other
)
/** Returns the fragment corresponding to the selected tab.*/
class ChooseSectionsPagerAdapter(private val context: Context, fm: FragmentManager)
: FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
override fun getItem(position: Int): Fragment {
return when (position){
0 -> ChooseFragmentApps()
1 -> ChooseFragmentOther()
else -> Fragment()
}
}
override fun getPageTitle(position: Int): CharSequence? {
return context.resources.getString(TAB_TITLES[position])
}
override fun getCount(): Int {
return when (action) {
"view" -> 1
else -> 2
}
}
}

View file

@ -1,52 +0,0 @@
package com.finnmglas.launcher.choose.apps
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import com.finnmglas.launcher.R
import com.finnmglas.launcher.choose.action
import com.finnmglas.launcher.extern.*
import com.finnmglas.launcher.choose.forApp
import kotlinx.android.synthetic.main.fragment_choose_apps.*
/** The 'Apps' Tab associated Fragment in the Chooser */
class ChooseFragmentApps : Fragment() {
/** Lifecycle functions */
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_choose_apps, container, false)
}
override fun onStart() {
super.onStart()
if (getSavedTheme(context!!) == "custom") {
fragment_choose_apps_container.setBackgroundColor(dominantColor)
}
// set up the list / recycler
val viewManager = LinearLayoutManager(context)
val viewAdapter = AppsRecyclerAdapter(
activity!!,
action,
forApp
)
fragment_choose_apps_recycler_view.apply {
// improve performance (since content changes don't change the layout size)
setHasFixedSize(true)
layoutManager = viewManager
adapter = viewAdapter
}
}
}

View file

@ -1,7 +0,0 @@
package com.finnmglas.launcher.choose.other
class OtherInfo(label: String, data: String, icon: String) {
var label: CharSequence? = label
var data: CharSequence? = data
var icon: CharSequence? = icon
}

View file

@ -1,4 +1,4 @@
package com.finnmglas.launcher.extern // replace with your package package com.finnmglas.launcher.libraries // replace with your package
// On GitHub: https://github.com/finnmglas/fontawesome-android // On GitHub: https://github.com/finnmglas/fontawesome-android

View file

@ -0,0 +1,141 @@
package com.finnmglas.launcher.list
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.viewpager.widget.ViewPager
import com.finnmglas.launcher.*
import com.finnmglas.launcher.settings.intendedSettingsPause
import com.google.android.material.tabs.TabLayout
import kotlinx.android.synthetic.main.list.*
import android.content.Context
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
import com.finnmglas.launcher.list.apps.ListFragmentApps
import com.finnmglas.launcher.list.other.ListFragmentOther
var intendedChoosePause = false // know when to close
// TODO: Better solution for this (used in list-fragments)
var intention = "view"
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 {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Initialise layout
setContentView(R.layout.list)
}
override fun onStart(){
super<AppCompatActivity>.onStart()
super<UIObject>.onStart()
}
override fun onPause() {
super.onPause()
intendedSettingsPause = false
if(!intendedChoosePause) finish()
}
override fun onResume() {
super.onResume()
intendedChoosePause = false
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_UNINSTALL) {
if (resultCode == Activity.RESULT_OK) {
Toast.makeText(this, getString(R.string.choose_removed_toast), Toast.LENGTH_LONG).show()
finish()
} else if (resultCode == Activity.RESULT_FIRST_USER) {
Toast.makeText(this, getString(R.string.choose_not_removed_toast), Toast.LENGTH_LONG).show()
finish()
}
}
}
override fun applyTheme() {
list_container.setBackgroundColor(dominantColor)
list_appbar.setBackgroundColor(dominantColor)
list_close.setTextColor(vibrantColor)
list_tabs.setSelectedTabIndicatorColor(vibrantColor)
}
override fun setOnClicks() {
list_close.setOnClickListener() { finish() }
}
override fun adjustLayout() {
// get info about which action this activity is open for
val bundle = intent.extras
if (bundle != null) {
intention = bundle.getString("intention")!! // why choose an app
if (intention != "view")
forApp = bundle.getString("forApp")!! // which app we choose
}
// Hide tabs for the "view" action
if (intention == "view") {
list_tabs.visibility = View.GONE
}
when (intention) {
"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(
R.string.choose_tab_app,
R.string.choose_tab_other
)
/**
* The [ListSectionsPagerAdapter] returns the fragment,
* which corresponds to the selected tab in [ListActivity].
*/
class ListSectionsPagerAdapter(private val context: Context, fm: FragmentManager)
: FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
override fun getItem(position: Int): Fragment {
return when (position){
0 -> ListFragmentApps()
1 -> ListFragmentOther()
else -> Fragment()
}
}
override fun getPageTitle(position: Int): CharSequence? {
return context.resources.getString(TAB_TITLES[position])
}
override fun getCount(): Int {
return when (intention) {
"view" -> 1
else -> 2
}
}
}

View file

@ -1,7 +1,12 @@
package com.finnmglas.launcher.choose.apps package com.finnmglas.launcher.list.apps
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
/**
* 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
var packageName: CharSequence? = null var packageName: CharSequence? = null

View file

@ -1,4 +1,4 @@
package com.finnmglas.launcher.choose.apps package com.finnmglas.launcher.list.apps
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
@ -12,27 +12,37 @@ import android.widget.ImageView
import android.widget.PopupMenu import android.widget.PopupMenu
import android.widget.TextView import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.finnmglas.launcher.R import com.finnmglas.launcher.*
import com.finnmglas.launcher.extern.* import com.finnmglas.launcher.libraries.*
import com.finnmglas.launcher.choose.intendedChoosePause import com.finnmglas.launcher.list.intendedChoosePause
class AppsRecyclerAdapter(val activity: Activity, val action: String?, 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>
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
View.OnClickListener { View.OnClickListener {
var textView: TextView = itemView.findViewById(R.id.choose_row_app_name) var textView: TextView = itemView.findViewById(R.id.list_apps_row_name)
var img: ImageView = itemView.findViewById(R.id.choose_row_app_icon) as ImageView var img: ImageView = itemView.findViewById(R.id.list_apps_row_icon) as ImageView
var menuDots: FontAwesome = itemView.findViewById(R.id.choose_row_app_menu) var menuDots: FontAwesome = itemView.findViewById(R.id.list_apps_row_menu)
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
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)!!
@ -60,10 +70,12 @@ class AppsRecyclerAdapter(val activity: Activity, val action: String?, val forAp
viewHolder.textView.text = appLabel viewHolder.textView.text = appLabel
viewHolder.img.setImageDrawable(appIcon) viewHolder.img.setImageDrawable(appIcon)
if (getSavedTheme(activity) == "dark") transformGrayscale(viewHolder.img) if (getSavedTheme(activity) == "dark") transformGrayscale(
viewHolder.img
)
// 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 {
@ -93,13 +105,18 @@ class AppsRecyclerAdapter(val activity: Activity, val action: String?, val forAp
val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE) val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE)
intent.data = Uri.parse("package:$appPackageName") intent.data = Uri.parse("package:$appPackageName")
intent.putExtra(Intent.EXTRA_RETURN_RESULT, true) intent.putExtra(Intent.EXTRA_RETURN_RESULT, true)
activity.startActivityForResult(intent, REQUEST_UNINSTALL) activity.startActivityForResult(intent,
REQUEST_UNINSTALL
)
true true
} }
R.id.app_menu_info -> { // open app settings R.id.app_menu_info -> { // open app settings
intendedChoosePause = true intendedChoosePause = true
openAppSettings(appPackageName, activity) openAppSettings(
appPackageName,
activity
)
true true
} }
else -> false else -> false
@ -114,7 +131,7 @@ class AppsRecyclerAdapter(val activity: Activity, val action: String?, val forAp
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(parent.context) val inflater = LayoutInflater.from(parent.context)
val view: View = inflater.inflate(R.layout.recycler_apps_row, parent, false) val view: View = inflater.inflate(R.layout.list_apps_row, parent, false)
return ViewHolder(view) return ViewHolder(view)
} }

View file

@ -0,0 +1,52 @@
package com.finnmglas.launcher.list.apps
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import com.finnmglas.launcher.R
import com.finnmglas.launcher.UIObject
import com.finnmglas.launcher.list.intention
import com.finnmglas.launcher.list.forApp
import com.finnmglas.launcher.dominantColor
import com.finnmglas.launcher.getSavedTheme
import kotlinx.android.synthetic.main.list_apps.*
/**
* 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 {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.list_apps, container, false)
}
override fun onStart() {
super<Fragment>.onStart()
super<UIObject>.onStart()
}
override fun applyTheme() {
list_apps_container.setBackgroundColor(dominantColor)
}
override fun setOnClicks() { }
override fun adjustLayout() {
// set up the list / recycler
list_apps_rview.apply {
// improve performance (since content changes don't change the layout size)
setHasFixedSize(true)
layoutManager = LinearLayoutManager(context)
adapter = AppsRecyclerAdapter(activity!!, intention, forApp)
}
}
}

View file

@ -1,4 +1,4 @@
package com.finnmglas.launcher.choose.other package com.finnmglas.launcher.list.other
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
@ -7,33 +7,35 @@ 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.extern.dominantColor import com.finnmglas.launcher.dominantColor
import com.finnmglas.launcher.extern.getSavedTheme import com.finnmglas.launcher.getSavedTheme
import kotlinx.android.synthetic.main.fragment_choose_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,
class ChooseFragmentOther : Fragment() { * when the `intention` for launching the ListActivity was to select something to be launched.
*
/** Lifecycle functions */ * It lists `other` things like internal activities to be launched as an action.
*/
class ListFragmentOther : Fragment() {
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
return inflater.inflate(R.layout.fragment_choose_other, container, false) return inflater.inflate(R.layout.list_other, container, false)
} }
override fun onStart() { override fun onStart() {
if (getSavedTheme(context!!) == "custom") { if (getSavedTheme(context!!) == "custom") {
fragment_choose_other_container.setBackgroundColor(dominantColor) list_other_container.setBackgroundColor(dominantColor)
} }
// set up the list / recycler // set up the list / recycler
val viewManager = LinearLayoutManager(context) val viewManager = LinearLayoutManager(context)
val viewAdapter = OtherRecyclerAdapter(activity!!) val viewAdapter = OtherRecyclerAdapter(activity!!)
fragment_choose_other_recycler_view.apply { list_other_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 = viewManager

View file

@ -0,0 +1,15 @@
package com.finnmglas.launcher.list.other
/**
* 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) {
var label: CharSequence? = label
var data: CharSequence? = data
var icon: CharSequence? = icon
}

View file

@ -1,4 +1,4 @@
package com.finnmglas.launcher.choose.other package com.finnmglas.launcher.list.other
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
@ -8,10 +8,17 @@ import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.finnmglas.launcher.R import com.finnmglas.launcher.R
import com.finnmglas.launcher.extern.* import com.finnmglas.launcher.REQUEST_CHOOSE_APP
import com.finnmglas.launcher.choose.forApp import com.finnmglas.launcher.libraries.*
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>() {
@ -19,8 +26,8 @@ class OtherRecyclerAdapter(val activity: Activity):
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
View.OnClickListener { View.OnClickListener {
var textView: TextView = itemView.findViewById(R.id.row_other_name) var textView: TextView = itemView.findViewById(R.id.list_other_row_name)
var iconView: FontAwesome = itemView.findViewById(R.id.row_other_fa_icon) var iconView: FontAwesome = itemView.findViewById(R.id.list_other_row_icon)
override fun onClick(v: View) { override fun onClick(v: View) {
@ -45,7 +52,7 @@ class OtherRecyclerAdapter(val activity: Activity):
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(parent.context) val inflater = LayoutInflater.from(parent.context)
val view: View = inflater.inflate(R.layout.recycler_other_row, parent, false) val view: View = inflater.inflate(R.layout.list_other_row, parent, false)
return ViewHolder(view) return ViewHolder(view)
} }

View file

@ -2,66 +2,51 @@ 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.WindowManager
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import com.finnmglas.launcher.R import com.finnmglas.launcher.*
import com.finnmglas.launcher.extern.*
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import kotlinx.android.synthetic.main.activity_settings.* import kotlinx.android.synthetic.main.settings.*
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
import com.finnmglas.launcher.settings.actions.SettingsFragmentActions
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
class SettingsActivity : AppCompatActivity() { /**
* The [SettingsActivity] is a tabbed activity:
/** Activity Lifecycle functions */ *
* | 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 {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setTheme( // Initialise layout
when (getSavedTheme(this)) { setContentView(R.layout.settings)
"dark" -> R.style.darkTheme
"finn" -> R.style.finnmglasTheme
else -> R.style.customTheme
}
)
setContentView(R.layout.activity_settings)
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
// set up tabs and swiping in settings
val sectionsPagerAdapter = SettingsSectionsPagerAdapter(this, supportFragmentManager) val sectionsPagerAdapter = SettingsSectionsPagerAdapter(this, supportFragmentManager)
val viewPager: ViewPager = findViewById(R.id.activity_settings_view_pager) val viewPager: ViewPager = findViewById(R.id.settings_viewpager)
viewPager.adapter = sectionsPagerAdapter viewPager.adapter = sectionsPagerAdapter
val tabs: TabLayout = findViewById(R.id.activity_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
activity_settings_close.setOnClickListener() { finish() }
// open device settings (see https://stackoverflow.com/a/62092663/12787264)
activity_settings_device_settings.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") {
activity_settings_container.setBackgroundColor(dominantColor)
activity_settings_app_bar.setBackgroundColor(dominantColor)
activity_settings_device_settings.setTextColor(vibrantColor)
activity_settings_close.setTextColor(vibrantColor)
activity_settings_tabs.setSelectedTabIndicatorColor(vibrantColor)
}
} }
override fun onResume() { override fun onResume() {
@ -74,27 +59,63 @@ 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()
editor.putString("action_$forApp", value.toString())
editor.apply()
loadSettings(sharedPref)
} }
else -> super.onActivityResult(requestCode, resultCode, data) else -> super.onActivityResult(requestCode, resultCode, data)
} }
} }
override fun applyTheme() {
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(
R.string.settings_tab_app,
R.string.settings_tab_theme,
R.string.settings_tab_launcher
)
class SettingsSectionsPagerAdapter(private val context: Context, fm: FragmentManager)
: FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
override fun getItem(position: Int): Fragment {
return when (position){
0 -> SettingsFragmentActions()
1 -> SettingsFragmentTheme()
2 -> SettingsFragmentMeta()
else -> Fragment()
}
}
override fun getPageTitle(position: Int): CharSequence? {
return context.resources.getString(TAB_TITLES[position])
}
override fun getCount(): Int { return 3 }
} }

View file

@ -1,36 +0,0 @@
package com.finnmglas.launcher.settings
import android.content.Context
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
import com.finnmglas.launcher.*
import com.finnmglas.launcher.settings.actions.SettingsFragmentApps
import com.finnmglas.launcher.settings.meta.SettingsFragmentMeta
import com.finnmglas.launcher.settings.theme.SettingsFragmentTheme
private val TAB_TITLES = arrayOf(
R.string.settings_tab_app,
R.string.settings_tab_theme,
R.string.settings_tab_launcher
)
/** Returns the fragment corresponding to the selected tab.*/
class SettingsSectionsPagerAdapter(private val context: Context, fm: FragmentManager)
: FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
override fun getItem(position: Int): Fragment {
return when (position){
0 -> SettingsFragmentApps()
1 -> SettingsFragmentTheme()
2 -> SettingsFragmentMeta()
else -> Fragment()
}
}
override fun getPageTitle(position: Int): CharSequence? {
return context.resources.getString(TAB_TITLES[position])
}
override fun getCount(): Int { return 3 }
}

View file

@ -1,7 +1,14 @@
package com.finnmglas.launcher.settings.actions package com.finnmglas.launcher.settings.actions
class ActionInfo(actionText: CharSequence, actionName: CharSequence, content: CharSequence) { /**
var actionName: CharSequence? = actionName * Stores information used in [ActionsRecyclerAdapter] rows.
var actionText: CharSequence? = actionText *
var content: CharSequence? = content * 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, data: CharSequence) {
val actionName: CharSequence? = actionName
val actionText: CharSequence? = actionText
val data: CharSequence? = data
} }

View file

@ -1,9 +1,7 @@
package com.finnmglas.launcher.settings.actions package com.finnmglas.launcher.settings.actions
import android.app.Activity import android.app.Activity
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
@ -11,10 +9,9 @@ import android.widget.Button
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.finnmglas.launcher.choose.ChooseActivity import com.finnmglas.launcher.*
import com.finnmglas.launcher.R import com.finnmglas.launcher.list.ListActivity
import com.finnmglas.launcher.extern.FontAwesome import com.finnmglas.launcher.libraries.FontAwesome
import com.finnmglas.launcher.extern.*
import com.finnmglas.launcher.settings.intendedSettingsPause import com.finnmglas.launcher.settings.intendedSettingsPause
import java.lang.Exception import java.lang.Exception
@ -26,19 +23,13 @@ class ActionsRecyclerAdapter(val activity: Activity):
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
View.OnClickListener { View.OnClickListener {
var textView: TextView = itemView.findViewById(R.id.row_action_name) var textView: TextView = itemView.findViewById(R.id.settings_actions_row_name)
var fontAwesome: FontAwesome = itemView.findViewById(R.id.row_app_fa_icon) var fontAwesome: FontAwesome = itemView.findViewById(R.id.settings_actions_row_icon)
var img: ImageView = itemView.findViewById(R.id.row_app_icon) as ImageView var img: ImageView = itemView.findViewById(R.id.settings_actions_row_icon_img) as ImageView
var chooseButton: Button = itemView.findViewById(R.id.row_choose_button) var chooseButton: Button = itemView.findViewById(R.id.settings_actions_row_button_choose)
var removeAction: FontAwesome = itemView.findViewById(R.id.row_remove_action) 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 context: Context = v.context
val content = actionsList[pos]
}
init { itemView.setOnClickListener(this) } init { itemView.setOnClickListener(this) }
} }
@ -46,25 +37,23 @@ 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
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() launcherPreferences.edit()
editor.putString("action_$actionName", "") // clear it .putString("action_$actionName", "") // clear it
editor.apply() .apply()
viewHolder.fontAwesome.visibility = View.INVISIBLE viewHolder.fontAwesome.visibility = View.INVISIBLE
viewHolder.img.visibility = View.INVISIBLE viewHolder.img.visibility = View.INVISIBLE
viewHolder.removeAction.visibility = View.GONE viewHolder.removeAction.visibility = View.GONE
viewHolder.chooseButton.visibility = View.VISIBLE viewHolder.chooseButton.visibility = View.VISIBLE
viewHolder.chooseButton.setOnClickListener{ chooseApp(actionName.toString()) } viewHolder.chooseButton.setOnClickListener{ chooseApp(actionName.toString()) }
if (getSavedTheme(activity) =="custom")
setButtonColor(viewHolder.chooseButton, vibrantColor) setButtonColor(viewHolder.chooseButton, vibrantColor)
} }
if (content!!.startsWith("launcher")) { if (content!!.startsWith("launcher")) {
@ -84,15 +73,16 @@ class ActionsRecyclerAdapter(val activity: Activity):
viewHolder.img.setImageDrawable(activity.packageManager.getApplicationIcon(content.toString())) viewHolder.img.setImageDrawable(activity.packageManager.getApplicationIcon(content.toString()))
viewHolder.img.setOnClickListener{ chooseApp(actionName.toString()) } viewHolder.img.setOnClickListener{ chooseApp(actionName.toString()) }
if (getSavedTheme(activity) == "dark") transformGrayscale(viewHolder.img) if (getSavedTheme(activity) == "dark") transformGrayscale(
viewHolder.img
)
} catch (e : Exception) { // the button is shown, user asked to select an action } catch (e : Exception) { // the button is shown, user asked to select an action
viewHolder.img.visibility = View.INVISIBLE viewHolder.img.visibility = View.INVISIBLE
viewHolder.removeAction.visibility = View.GONE viewHolder.removeAction.visibility = View.GONE
viewHolder.chooseButton.visibility = View.VISIBLE viewHolder.chooseButton.visibility = View.VISIBLE
viewHolder.chooseButton.setOnClickListener{ chooseApp(actionName.toString()) } viewHolder.chooseButton.setOnClickListener{ chooseApp(actionName.toString()) }
if (getSavedTheme(activity) =="custom") setButtonColor(viewHolder.chooseButton, vibrantColor)
setButtonColor(viewHolder.chooseButton, vibrantColor)
} }
} }
} }
@ -101,28 +91,46 @@ class ActionsRecyclerAdapter(val activity: Activity):
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(parent.context) val inflater = LayoutInflater.from(parent.context)
val view: View = inflater.inflate(R.layout.recycler_actions_row, parent, false) val view: View = inflater.inflate(R.layout.settings_actions_row, parent, false)
return ViewHolder(view) return ViewHolder(view)
} }
init { init {
actionsList = ArrayList() actionsList = ArrayList()
actionsList.add(ActionInfo(activity.getString(R.string.settings_choose_up),"upApp", upApp)) actionsList.add(ActionInfo(activity.getString(R.string.settings_choose_up),"upApp",
actionsList.add(ActionInfo(activity.getString(R.string.settings_choose_down),"downApp", downApp)) upApp
actionsList.add(ActionInfo(activity.getString(R.string.settings_choose_left), "leftApp", leftApp)) ))
actionsList.add(ActionInfo(activity.getString(R.string.settings_choose_right), "rightApp", rightApp)) actionsList.add(ActionInfo(activity.getString(R.string.settings_choose_down),"downApp",
actionsList.add(ActionInfo(activity.getString(R.string.settings_choose_vol_up), "volumeUpApp", volumeUpApp)) downApp
actionsList.add(ActionInfo(activity.getString(R.string.settings_choose_vol_down), "volumeDownApp", volumeDownApp)) ))
actionsList.add(ActionInfo(activity.getString(R.string.settings_choose_double_click), "doubleClickApp", doubleClickApp)) actionsList.add(ActionInfo(activity.getString(R.string.settings_choose_left), "leftApp",
actionsList.add(ActionInfo(activity.getString(R.string.settings_choose_long_click), "longClickApp", longClickApp)) leftApp
))
actionsList.add(ActionInfo(activity.getString(R.string.settings_choose_right), "rightApp",
rightApp
))
actionsList.add(ActionInfo(activity.getString(R.string.settings_choose_vol_up), "volumeUpApp",
volumeUpApp
))
actionsList.add(ActionInfo(activity.getString(R.string.settings_choose_vol_down), "volumeDownApp",
volumeDownApp
))
actionsList.add(ActionInfo(activity.getString(R.string.settings_choose_double_click), "doubleClickApp",
doubleClickApp
))
actionsList.add(ActionInfo(activity.getString(R.string.settings_choose_long_click), "longClickApp",
longClickApp
))
} }
/* */ /* */
private fun chooseApp(forAction: String) { private fun chooseApp(forAction: String) {
val intent = Intent(activity, ChooseActivity::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, REQUEST_CHOOSE_APP) activity.startActivityForResult(intent,
REQUEST_CHOOSE_APP
)
} }
} }

View file

@ -10,55 +10,62 @@ import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.finnmglas.launcher.choose.ChooseActivity import com.finnmglas.launcher.*
import com.finnmglas.launcher.R import com.finnmglas.launcher.list.ListActivity
import com.finnmglas.launcher.extern.*
import com.finnmglas.launcher.settings.intendedSettingsPause import com.finnmglas.launcher.settings.intendedSettingsPause
import kotlinx.android.synthetic.main.fragment_settings_apps.* 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 SettingsFragmentApps : Fragment() { class SettingsFragmentActions : Fragment(), UIObject {
/** Lifecycle functions */
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
return inflater.inflate(R.layout.fragment_settings_apps, container, false) return inflater.inflate(R.layout.settings_actions, container, false)
} }
override fun onStart() { override fun onStart() {
super<Fragment>.onStart()
if (getSavedTheme(context!!) == "custom") { super<UIObject>.onStart()
fragment_settings_apps_container.setBackgroundColor(dominantColor)
setButtonColor(fragment_settings_apps_btn, vibrantColor)
setButtonColor(fragment_settings_apps_install_btn, vibrantColor)
}
// set up the list / recycler // set up the list / recycler
val actionViewManager = LinearLayoutManager(context) val actionViewManager = LinearLayoutManager(context)
val actionViewAdapter = ActionsRecyclerAdapter( activity!! ) val actionViewAdapter = ActionsRecyclerAdapter( activity!! )
activity_settings_actions_recycler_view.apply { settings_actions_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 = actionViewManager layoutManager = actionViewManager
adapter = actionViewAdapter adapter = actionViewAdapter
} }
}
override fun applyTheme() {
settings_actions_container.setBackgroundColor(dominantColor)
setButtonColor(settings_actions_button_view_apps, vibrantColor)
setButtonColor(settings_actions_button_install_apps, vibrantColor)
}
override fun setOnClicks() {
// App management buttons // App management buttons
fragment_settings_apps_btn.setOnClickListener{ settings_actions_button_view_apps.setOnClickListener{
val intent = Intent(this.context, ChooseActivity::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)
} }
fragment_settings_apps_install_btn.setOnClickListener{ settings_actions_button_install_apps.setOnClickListener{
try { try {
val rateIntent = Intent( val rateIntent = Intent(
Intent.ACTION_VIEW, Intent.ACTION_VIEW,
@ -70,7 +77,5 @@ class SettingsFragmentApps : 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
@ -13,131 +12,33 @@ import androidx.fragment.app.Fragment
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import com.finnmglas.launcher.*
import com.finnmglas.launcher.tutorial.TutorialActivity import com.finnmglas.launcher.tutorial.TutorialActivity
import com.finnmglas.launcher.R
import com.finnmglas.launcher.extern.*
import com.finnmglas.launcher.settings.intendedSettingsPause import com.finnmglas.launcher.settings.intendedSettingsPause
import kotlinx.android.synthetic.main.fragment_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.
class SettingsFragmentMeta : Fragment() { *
* It is used to change settings and access resources about Launcher,
/** Lifecycle functions */ * that are not directly related to the behaviour of the app itself.
*
* (greek `meta` = above, next level)
*/
class SettingsFragmentMeta : Fragment(), UIObject {
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
return inflater.inflate(R.layout.fragment_settings_meta, container, false) return inflater.inflate(R.layout.settings_meta, container, false)
} }
override fun onStart() { override fun onStart() {
super<Fragment>.onStart()
if (getSavedTheme(context!!) == "custom") { super<UIObject>.onStart()
fragment_settings_meta_container.setBackgroundColor(dominantColor)
setButtonColor(fragment_settings_meta_select_launcher_btn, vibrantColor)
setButtonColor(fragment_settings_meta_view_tutorial_btn, vibrantColor)
setButtonColor(fragment_settings_meta_reset_settings_btn, vibrantColor)
setButtonColor(fragment_settings_meta_contact_btn, vibrantColor)
setButtonColor(fragment_settings_meta_donate_btn, vibrantColor)
fragment_settings_meta_footer_play_icon.setTextColor(vibrantColor)
fragment_settings_meta_footer_github_icon.setTextColor(vibrantColor)
fragment_settings_meta_footer_globe_icon.setTextColor(vibrantColor)
}
// Button onClicks
fragment_settings_meta_select_launcher_btn.setOnClickListener {
intendedSettingsPause = true
// on newer sdk: choose launcher
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val callHomeSettingIntent = Intent(Settings.ACTION_HOME_SETTINGS)
startActivity(callHomeSettingIntent)
}
// on older sdk: manage app details
else {
AlertDialog.Builder(this.context!!, R.style.AlertDialogCustom)
.setTitle(getString(R.string.alert_cant_choose_launcher))
.setMessage(getString(R.string.alert_cant_choose_launcher_message))
.setPositiveButton(android.R.string.yes,
DialogInterface.OnClickListener { _, _ ->
try {
openAppSettings(this.context!!.packageName, this.context!!)
} catch ( e : ActivityNotFoundException) {
val intent = Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS)
startActivity(intent)
}
})
.setNegativeButton(android.R.string.no, null)
.setIcon(android.R.drawable.ic_dialog_info)
.show()
}
}
fragment_settings_meta_view_tutorial_btn.setOnClickListener {
intendedSettingsPause = true
startActivity(Intent(this.context, TutorialActivity::class.java))
}
// prompting for settings-reset confirmation
fragment_settings_meta_reset_settings_btn.setOnClickListener {
AlertDialog.Builder(this.context!!, R.style.AlertDialogCustom)
.setTitle(getString(R.string.settings_reset))
.setMessage(getString(R.string.settings_reset_message))
.setPositiveButton(android.R.string.yes,
DialogInterface.OnClickListener { _, _ ->
resetSettings(this.context!!.getSharedPreferences(getString(R.string.preference_file_key),
Context.MODE_PRIVATE), this.context!!)
activity!!.finish()
})
.setNegativeButton(android.R.string.no, null)
.setIcon(android.R.drawable.ic_dialog_alert)
.show()
}
// Footer onClicks
fragment_settings_meta_footer_github_icon.setOnClickListener {
intendedSettingsPause = true
openNewTabWindow(getString(R.string.settings_footer_repo), this.context!!)
}
// rate app
fragment_settings_meta_footer_play_icon.setOnClickListener {
try {
val rateIntent = rateIntentForUrl("market://details")
intendedSettingsPause = true
startActivity(rateIntent)
} catch (e: ActivityNotFoundException) {
val rateIntent = rateIntentForUrl("https://play.google.com/store/apps/details")
intendedSettingsPause = true
startActivity(rateIntent)
}
}
fragment_settings_meta_footer_globe_icon.setOnClickListener {
intendedSettingsPause = true
openNewTabWindow(getString(R.string.settings_footer_web), this.context!!)
}
// contact developer
fragment_settings_meta_contact_btn.setOnClickListener {
intendedSettingsPause = true
openNewTabWindow(getString(R.string.settings_meta_contact_url), context!!)
}
// donate
fragment_settings_meta_donate_btn.setOnClickListener {
intendedSettingsPause = true
openNewTabWindow(getString(R.string.settings_meta_donate_url), context!!)
}
super.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 ^^
@ -156,4 +57,120 @@ class SettingsFragmentMeta : Fragment() {
intent.addFlags(flags) intent.addFlags(flags)
return intent return intent
} }
override fun applyTheme() {
settings_meta_container.setBackgroundColor(dominantColor)
setButtonColor(settings_meta_button_select_launcher, vibrantColor)
setButtonColor(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_github.setTextColor(vibrantColor)
settings_meta_icon_globe.setTextColor(vibrantColor)
}
override fun setOnClicks() {
// Button onClicks
settings_meta_button_select_launcher.setOnClickListener {
intendedSettingsPause = true
// on newer sdk: choose launcher
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val callHomeSettingIntent = Intent(Settings.ACTION_HOME_SETTINGS)
startActivity(callHomeSettingIntent)
}
// on older sdk: manage app details
else {
AlertDialog.Builder(this.context!!, R.style.AlertDialogCustom)
.setTitle(getString(R.string.alert_cant_choose_launcher))
.setMessage(getString(R.string.alert_cant_choose_launcher_message))
.setPositiveButton(android.R.string.yes,
DialogInterface.OnClickListener { _, _ ->
try {
openAppSettings(
this.context!!.packageName,
this.context!!
)
} catch ( e : ActivityNotFoundException) {
val intent = Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS)
startActivity(intent)
}
})
.setNegativeButton(android.R.string.no, null)
.setIcon(android.R.drawable.ic_dialog_info)
.show()
}
}
settings_meta_button_view_tutorial.setOnClickListener {
intendedSettingsPause = true
startActivity(Intent(this.context, TutorialActivity::class.java))
}
// prompting for settings-reset confirmation
settings_meta_button_reset_settings.setOnClickListener {
AlertDialog.Builder(this.context!!, R.style.AlertDialogCustom)
.setTitle(getString(R.string.settings_reset))
.setMessage(getString(R.string.settings_reset_message))
.setPositiveButton(android.R.string.yes,
DialogInterface.OnClickListener { _, _ ->
resetSettings(this.context!!)
activity!!.finish()
})
.setNegativeButton(android.R.string.no, null)
.setIcon(android.R.drawable.ic_dialog_alert)
.show()
}
// Footer onClicks
settings_meta_icon_github.setOnClickListener {
intendedSettingsPause = true
openNewTabWindow(
getString(R.string.settings_footer_repo),
this.context!!
)
}
// rate app
settings_meta_icon_google_play.setOnClickListener {
try {
val rateIntent = rateIntentForUrl("market://details")
intendedSettingsPause = true
startActivity(rateIntent)
} catch (e: ActivityNotFoundException) {
val rateIntent = rateIntentForUrl("https://play.google.com/store/apps/details")
intendedSettingsPause = true
startActivity(rateIntent)
}
}
settings_meta_icon_globe.setOnClickListener {
intendedSettingsPause = true
openNewTabWindow(
getString(R.string.settings_footer_web),
this.context!!
)
}
// contact developer
settings_meta_button_contact.setOnClickListener {
intendedSettingsPause = true
openNewTabWindow(
getString(R.string.settings_meta_contact_url),
context!!
)
}
// donate
settings_meta_button_donate.setOnClickListener {
intendedSettingsPause = true
openNewTabWindow(
getString(R.string.settings_meta_donate_url),
context!!
)
}
}
} }

View file

@ -1,9 +1,7 @@
package com.finnmglas.launcher.settings.theme package com.finnmglas.launcher.settings.theme
import android.Manifest import android.Manifest
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
@ -16,73 +14,27 @@ import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.palette.graphics.Palette import androidx.palette.graphics.Palette
import com.finnmglas.launcher.R import com.finnmglas.launcher.*
import com.finnmglas.launcher.extern.*
import com.finnmglas.launcher.settings.intendedSettingsPause import com.finnmglas.launcher.settings.intendedSettingsPause
import kotlinx.android.synthetic.main.fragment_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.
class SettingsFragmentTheme : Fragment() { *
* It is used to change themes, select wallpapers ... theme related stuff
/** Lifecycle functions */ */
class SettingsFragmentTheme : Fragment(), UIObject {
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
return inflater.inflate(R.layout.fragment_settings_theme, container, false) return inflater.inflate(R.layout.settings_theme, container, false)
} }
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" -> fragment_settings_theme_select_dark_btn.visibility = View.INVISIBLE
"finn" -> fragment_settings_theme_select_finn_btn.visibility = View.INVISIBLE
"custom" -> {
fragment_settings_theme_select_custom_btn.text = getString(R.string.settings_select_image)
fragment_settings_theme_container.setBackgroundColor(dominantColor)
setButtonColor(fragment_settings_theme_select_finn_btn, vibrantColor)
setButtonColor(fragment_settings_theme_select_dark_btn, vibrantColor)
setButtonColor(fragment_settings_theme_select_custom_btn, vibrantColor)
setButtonColor(fragment_settings_theme_custom_examples_btn, vibrantColor)
}
}
// Theme changing buttons
fragment_settings_theme_select_dark_btn.setOnClickListener {
intendedSettingsPause = true
saveTheme(context!!, "dark")
activity!!.recreate()
}
fragment_settings_theme_select_finn_btn.setOnClickListener {
intendedSettingsPause = true
saveTheme(context!!, "finn")
activity!!.recreate()
}
fragment_settings_theme_select_custom_btn.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()
}
fragment_settings_theme_custom_examples_btn.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?) {
@ -94,8 +46,6 @@ class SettingsFragmentTheme : Fragment() {
} }
} }
/** 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/*"
@ -114,7 +64,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
@ -128,23 +77,106 @@ class SettingsFragmentTheme : Fragment() {
// never let dominantColor equal vibrantColor // never let dominantColor equal vibrantColor
if(dominantColor == vibrantColor) { if(dominantColor == vibrantColor) {
vibrantColor = manipulateColor(vibrantColor, 1.2F) vibrantColor =
dominantColor = manipulateColor(dominantColor, 0.8F) manipulateColor(
vibrantColor,
1.2F
)
dominantColor =
manipulateColor(
dominantColor,
0.8F
)
} }
/* Save image Uri as string */ /* Save image Uri as string */
val editor: SharedPreferences.Editor = context!!.getSharedPreferences( launcherPreferences.edit()
context!!.getString(R.string.preference_file_key), Context.MODE_PRIVATE).edit() .putString("background_uri", imageUri.toString())
editor.putString("background_uri", imageUri.toString()) .putInt("custom_dominant", dominantColor)
editor.putInt("custom_dominant", dominantColor) .putInt("custom_vibrant", vibrantColor)
editor.putInt("custom_vibrant", vibrantColor) .apply()
editor.apply()
saveTheme(context!!, "custom") saveTheme("custom")
intendedSettingsPause = true intendedSettingsPause = true
activity!!.recreate() activity!!.recreate()
} }
} }
} }
} }
override fun applyTheme() {
// 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 {
dominantColor = resources.getColor(R.color.darkTheme_background_color)
vibrantColor = resources.getColor(R.color.darkTheme_accent_color)
launcherPreferences.edit()
.putString("background_uri", "")
.putInt("custom_dominant", dominantColor)
.putInt("custom_vibrant", vibrantColor)
.apply()
saveTheme("dark")
intendedSettingsPause = true
activity!!.recreate()
}
settings_theme_finn_button_select.setOnClickListener {
dominantColor = resources.getColor(R.color.finnmglasTheme_background_color)
vibrantColor = resources.getColor(R.color.finnmglasTheme_accent_color)
launcherPreferences.edit()
.putString("background_uri", "")
.putInt("custom_dominant", dominantColor)
.putInt("custom_vibrant", vibrantColor)
.apply()
saveTheme("finn")
intendedSettingsPause = true
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,68 +1,44 @@
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.*
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.finnmglas.launcher.R import com.finnmglas.launcher.*
import com.finnmglas.launcher.extern.* import kotlinx.android.synthetic.main.tutorial.*
import kotlinx.android.synthetic.main.activity_tutorial.*
/**
class TutorialActivity : AppCompatActivity(){ * The [TutorialActivity] is displayed automatically on new installations.
* It can also be opened from Settings.
/** Variables for this activity */ *
* It tells the user about the concept behind launcher
* and helps with the setup process (on new installations)
*/
class TutorialActivity: AppCompatActivity(), UIObject {
private var menuNumber = 0 private var menuNumber = 0
private var defaultApps = mutableListOf<String>() private var defaultApps = mutableListOf<String>()
private var isFirstTime = false private var isFirstTime = false
/** Activity Lifecycle functions */
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
// Flags // Initialise layout
window.setFlags( setContentView(R.layout.tutorial)
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
)
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
setTheme(
when (getSavedTheme(this)) {
"dark" -> R.style.darkTheme
"finn" -> R.style.finnmglasTheme
else -> R.style.finnmglasTheme
}
)
setContentView(R.layout.activity_tutorial)
if (getSavedTheme(this) == "custom") {
activity_firststartup_app_bar.setBackgroundColor(dominantColor)
activity_firststartup_container.setBackgroundColor(dominantColor)
activity_firststartup_close.setTextColor(vibrantColor)
}
activity_firststartup_hint_text.blink() // animate
loadMenu(this) loadMenu(this)
val sharedPref = this.getSharedPreferences(getString(R.string.preference_file_key), Context.MODE_PRIVATE) // Check if it is the first time starting the app
isFirstTime = !launcherPreferences.getBoolean("startedBefore", false)
isFirstTime = !sharedPref.getBoolean("startedBefore", false)
if (isFirstTime) if (isFirstTime)
defaultApps = resetSettings(sharedPref, this) // UP, DOWN, RIGHT, LEFT, VOLUME_UP, VOLUME_DOWN defaultApps = resetSettings(this) // UP, DOWN, RIGHT, LEFT, VOLUME_UP, VOLUME_DOWN
else else tutorial_appbar.visibility = View.VISIBLE
activity_firststartup_app_bar.visibility = View.VISIBLE
// As older APIs somehow do not recognize the xml defined onClick
activity_firststartup_close.setOnClickListener() { finish() }
} }
/** Touch- and Key-related functions to navigate */ override fun onStart() {
super<AppCompatActivity>.onStart()
super<UIObject>.onStart()
}
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){
@ -85,40 +61,43 @@ 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){
val entry = intro[menuNumber].split("|").toTypedArray() //heading|infoText|hintText|size val entry = intro[menuNumber].split("|").toTypedArray() //heading|infoText|hintText|size
activity_firststartup_section_heading.text = entry[0] tutorial_page_heading.text = entry[0]
if (entry[4] == "1" && isFirstTime) if (entry[4] == "1" && isFirstTime)
activity_firststartup_descriptive_text.text = String.format(entry[1], tutorial_page_text.text = String.format(entry[1],
defaultApps[0], defaultApps[1], defaultApps[2], defaultApps[3], defaultApps[4], defaultApps[5]) defaultApps[0], defaultApps[1], defaultApps[2], defaultApps[3], defaultApps[4], defaultApps[5])
else if (entry[4] == "1" && !isFirstTime) else if (entry[4] == "1" && !isFirstTime)
activity_firststartup_descriptive_text.text = String.format(entry[1], tutorial_page_text.text = String.format(entry[1],
"-", "-", "-", "-", "-", "-") "-", "-", "-", "-", "-", "-")
else activity_firststartup_descriptive_text.text = entry[1] else tutorial_page_text.text = entry[1]
activity_firststartup_hint_text.text = entry[2] tutorial_page_hint.text = entry[2]
activity_firststartup_descriptive_text.setTextSize(TypedValue.COMPLEX_UNIT_SP, entry[3].toFloat()) tutorial_page_text.setTextSize(TypedValue.COMPLEX_UNIT_SP, entry[3].toFloat())
} 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 applyTheme() {
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

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="-75%p"
android:toXDelta="0%p"
android:interpolator="@android:anim/decelerate_interpolator"
android:duration="100"/>
</set>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="75%p"
android:toXDelta="0%p"
android:interpolator="@android:anim/decelerate_interpolator"
android:duration="100"/>
</set>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="-75%p"
android:toYDelta="0%p"
android:interpolator="@android:anim/decelerate_interpolator"
android:duration="100"/>
</set>

View file

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_choose_apps_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorPrimary"
android:gravity="center|top"
android:orientation="vertical"
tools:context=".choose.apps.ChooseFragmentApps">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/fragment_choose_apps_recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>

View file

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_choose_other_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorPrimary"
android:gravity="center|top"
android:orientation="vertical"
tools:context=".choose.other.ChooseFragmentOther">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/fragment_choose_other_recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>

View file

@ -1,60 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_settings_apps_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorPrimary"
android:gravity="center|top"
android:orientation="vertical"
android:paddingLeft="32sp"
android:paddingTop="16sp"
android:paddingRight="32sp"
tools:context=".settings.actions.SettingsFragmentApps">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/activity_settings_actions_recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toTopOf="@+id/settings_app_btn_layout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</androidx.recyclerview.widget.RecyclerView>
<LinearLayout
android:id="@+id/settings_app_btn_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="@+id/fragment_settings_apps_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/settings_apps"
android:textAllCaps="false" />
<Button
android:id="@+id/fragment_settings_apps_install_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/settings_install"
android:textAllCaps="false" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>

View file

@ -1,17 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:custom="http://schemas.android.com/apk/res-auto" xmlns:custom="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main_container" android:id="@+id/home_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/colorPrimary" android:background="?attr/colorPrimary"
android:longClickable="false" android:longClickable="false"
tools:context=".MainActivity"> tools:context=".HomeActivity">
<ImageView <ImageView
android:id="@+id/activity_main_background_image" android:id="@+id/home_background_image"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:adjustViewBounds="true" android:adjustViewBounds="true"
@ -20,11 +21,10 @@
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
<TextView <TextView
android:id="@+id/activity_main_date_view" android:id="@+id/home_date_view"
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"
@ -33,11 +33,10 @@
app:layout_constraintVertical_bias="0.45" /> app:layout_constraintVertical_bias="0.45" />
<TextView <TextView
android:id="@+id/activity_main_time_view" android:id="@+id/home_time_view"
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"
@ -45,11 +44,10 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<com.finnmglas.launcher.extern.FontAwesome <com.finnmglas.launcher.libraries.FontAwesome
android:id="@+id/activity_main_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

@ -1,16 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:custom="http://schemas.android.com/apk/res-auto" xmlns:custom="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_choose_container" android:id="@+id/list_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/colorPrimary" android:background="?attr/colorPrimary"
tools:context=".choose.ChooseActivity"> tools:context=".list.ListActivity">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/activity_choose_app_bar" android:id="@+id/list_appbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
@ -23,7 +24,7 @@
android:layout_height="match_parent"> android:layout_height="match_parent">
<TextView <TextView
android:id="@+id/activity_choose_heading" android:id="@+id/list_heading"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
@ -36,15 +37,14 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<com.finnmglas.launcher.extern.FontAwesome <com.finnmglas.launcher.libraries.FontAwesome
android:id="@+id/activity_choose_close" android:id="@+id/list_close"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="8dp" android:layout_marginEnd="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"
@ -57,7 +57,7 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.tabs.TabLayout <com.google.android.material.tabs.TabLayout
android:id="@+id/activity_choose_tabs" android:id="@+id/list_tabs"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
custom:tabTextColor="?attr/android:textColor" /> custom:tabTextColor="?attr/android:textColor" />
@ -65,13 +65,13 @@
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager <androidx.viewpager.widget.ViewPager
android:id="@+id/activity_choose_view_pager" android:id="@+id/list_viewpager"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/activity_choose_app_bar" app:layout_constraintTop_toBottomOf="@id/list_appbar"
custom:layout_behavior="@string/appbar_scrolling_view_behavior" /> custom:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/list_apps_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list_apps_rview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,13 +1,15 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/list_apps_row_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="15sp"> android:layout_margin="15sp">
<ImageView <ImageView
android:id="@+id/choose_row_app_icon" android:id="@+id/list_apps_row_icon"
android:layout_width="40sp" android:layout_width="40sp"
android:layout_height="40sp" android:layout_height="40sp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
@ -16,7 +18,7 @@
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
<TextView <TextView
android:id="@+id/choose_row_app_name" android:id="@+id/list_apps_row_name"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="60sp" android:layout_marginStart="60sp"
@ -27,12 +29,12 @@
android:text="" android:text=""
android:textSize="20sp" android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/choose_row_app_menu" app:layout_constraintEnd_toStartOf="@+id/list_apps_row_menu"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<com.finnmglas.launcher.extern.FontAwesome <com.finnmglas.launcher.libraries.FontAwesome
android:id="@+id/choose_row_app_menu" android:id="@+id/list_apps_row_menu"
android:layout_width="30sp" android:layout_width="30sp"
android:layout_height="0dp" android:layout_height="0dp"
android:gravity="center" android:gravity="center"

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/list_other_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list_other_rview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,13 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/list_other_row_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="15sp"> android:layout_margin="15sp">
<com.finnmglas.launcher.extern.FontAwesome <com.finnmglas.launcher.libraries.FontAwesome
android:id="@+id/row_other_fa_icon" android:id="@+id/list_other_row_icon"
android:layout_width="40sp" android:layout_width="40sp"
android:layout_height="40sp" android:layout_height="40sp"
android:gravity="center" android:gravity="center"
@ -18,7 +19,7 @@
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
android:id="@+id/row_other_name" android:id="@+id/list_other_row_name"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="60sp" android:layout_marginStart="60sp"

View file

@ -4,13 +4,13 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:custom="http://schemas.android.com/apk/res-auto" xmlns:custom="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_settings_container" android:id="@+id/settings_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".settings.SettingsActivity"> tools:context=".settings.SettingsActivity">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/activity_settings_app_bar" android:id="@+id/settings_appbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
@ -19,7 +19,7 @@
android:layout_height="match_parent"> android:layout_height="match_parent">
<TextView <TextView
android:id="@+id/activity_settings_heading" android:id="@+id/settings_heading"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
@ -33,15 +33,13 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<com.finnmglas.launcher.extern.FontAwesome <com.finnmglas.launcher.libraries.FontAwesome
android:id="@+id/activity_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"
@ -52,8 +50,8 @@
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
custom:type="solid" /> custom:type="solid" />
<com.finnmglas.launcher.extern.FontAwesome <com.finnmglas.launcher.libraries.FontAwesome
android:id="@+id/activity_settings_device_settings" android:id="@+id/settings_system"
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_marginLeft="8dp"
@ -67,11 +65,12 @@
custom:layout_constraintBottom_toBottomOf="parent" custom:layout_constraintBottom_toBottomOf="parent"
custom:layout_constraintStart_toStartOf="parent" custom:layout_constraintStart_toStartOf="parent"
custom:layout_constraintTop_toTopOf="parent" custom:layout_constraintTop_toTopOf="parent"
custom:type="solid" /> custom:type="solid"
android:layout_marginStart="8dp" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.tabs.TabLayout <com.google.android.material.tabs.TabLayout
android:id="@+id/activity_settings_tabs" android:id="@+id/settings_tabs"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:tabTextColor="?attr/android:textColor" /> app:tabTextColor="?attr/android:textColor" />
@ -79,7 +78,7 @@
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager <androidx.viewpager.widget.ViewPager
android:id="@+id/activity_settings_view_pager" android:id="@+id/settings_viewpager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" /> app:layout_behavior="@string/appbar_scrolling_view_behavior" />

View file

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/settings_actions_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorPrimary"
android:paddingLeft="32sp"
android:paddingTop="16sp"
android:paddingRight="32sp">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/settings_actions_rview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toTopOf="@+id/settings_actions_buttons"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</androidx.recyclerview.widget.RecyclerView>
<LinearLayout
android:id="@+id/settings_actions_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="@+id/settings_actions_button_view_apps"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/settings_apps"
android:textAllCaps="false" />
<Button
android:id="@+id/settings_actions_button_install_apps"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/settings_install"
android:textAllCaps="false" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,12 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/settings_actions_row_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<TextView <TextView
android:id="@+id/row_action_name" android:id="@+id/settings_actions_row_name"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="5dp" android:layout_marginEnd="5dp"
@ -15,12 +17,12 @@
android:text="" android:text=""
android:textSize="20sp" android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/row_choose_button" app:layout_constraintEnd_toStartOf="@id/settings_actions_row_button_choose"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<Button <Button
android:id="@+id/row_choose_button" android:id="@+id/settings_actions_row_button_choose"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/settings_choose_btn" android:text="@string/settings_choose_btn"
@ -30,38 +32,38 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<com.finnmglas.launcher.extern.FontAwesome <com.finnmglas.launcher.libraries.FontAwesome
android:id="@+id/row_app_fa_icon" android:id="@+id/settings_actions_row_icon"
android:layout_width="@dimen/app_icon_side" android:layout_width="@dimen/app_icon_side"
android:layout_height="@dimen/app_icon_side" android:layout_height="@dimen/app_icon_side"
android:gravity="center" android:gravity="center"
android:textSize="30sp" android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/row_choose_button" app:layout_constraintEnd_toEndOf="@id/settings_actions_row_button_choose"
app:layout_constraintHorizontal_bias="0.2" app:layout_constraintHorizontal_bias="0.2"
app:layout_constraintStart_toStartOf="@+id/row_choose_button" app:layout_constraintStart_toStartOf="@+id/settings_actions_row_button_choose"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<ImageView <ImageView
android:id="@+id/row_app_icon" android:id="@+id/settings_actions_row_icon_img"
android:layout_width="@dimen/app_icon_side" android:layout_width="@dimen/app_icon_side"
android:layout_height="@dimen/app_icon_side" android:layout_height="@dimen/app_icon_side"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/row_choose_button" app:layout_constraintEnd_toEndOf="@id/settings_actions_row_button_choose"
app:layout_constraintHorizontal_bias="0.2" app:layout_constraintHorizontal_bias="0.2"
app:layout_constraintStart_toStartOf="@+id/row_choose_button" app:layout_constraintStart_toStartOf="@+id/settings_actions_row_button_choose"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
<com.finnmglas.launcher.extern.FontAwesome <com.finnmglas.launcher.libraries.FontAwesome
android:id="@+id/row_remove_action" android:id="@+id/settings_actions_row_remove"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="8sp" android:padding="8sp"
android:text="@string/fas_times" android:text="@string/fas_times"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/row_app_icon" app:layout_constraintStart_toEndOf="@+id/settings_actions_row_icon_img"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto" xmlns:custom="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_settings_meta_container" android:id="@+id/settings_meta_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/colorPrimary" android:background="?attr/colorPrimary"
@ -15,21 +15,21 @@
tools:context=".settings.meta.SettingsFragmentMeta"> tools:context=".settings.meta.SettingsFragmentMeta">
<Button <Button
android:id="@+id/fragment_settings_meta_select_launcher_btn" android:id="@+id/settings_meta_button_select_launcher"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/settings_select_launcher" android:text="@string/settings_select_launcher"
android:textAllCaps="false" /> android:textAllCaps="false" />
<Button <Button
android:id="@+id/fragment_settings_meta_view_tutorial_btn" android:id="@+id/settings_meta_button_view_tutorial"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/settings_show_tutorial" android:text="@string/settings_show_tutorial"
android:textAllCaps="false" /> android:textAllCaps="false" />
<Button <Button
android:id="@+id/fragment_settings_meta_reset_settings_btn" android:id="@+id/settings_meta_button_reset_settings"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="32sp" android:layout_marginBottom="32sp"
@ -37,6 +37,7 @@
android:textAllCaps="false" /> android:textAllCaps="false" />
<LinearLayout <LinearLayout
android:id="@+id/settings_meta_layout_icons"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="32sp" android:layout_marginTop="32sp"
@ -44,8 +45,8 @@
android:gravity="center" android:gravity="center"
android:orientation="horizontal"> android:orientation="horizontal">
<com.finnmglas.launcher.extern.FontAwesome <com.finnmglas.launcher.libraries.FontAwesome
android:id="@+id/fragment_settings_meta_footer_play_icon" android:id="@+id/settings_meta_icon_google_play"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
@ -60,8 +61,8 @@
android:textSize="40sp" android:textSize="40sp"
custom:type="brands" /> custom:type="brands" />
<com.finnmglas.launcher.extern.FontAwesome <com.finnmglas.launcher.libraries.FontAwesome
android:id="@+id/fragment_settings_meta_footer_github_icon" android:id="@+id/settings_meta_icon_github"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
@ -76,8 +77,8 @@
android:textSize="40sp" android:textSize="40sp"
custom:type="brands" /> custom:type="brands" />
<com.finnmglas.launcher.extern.FontAwesome <com.finnmglas.launcher.libraries.FontAwesome
android:id="@+id/fragment_settings_meta_footer_globe_icon" android:id="@+id/settings_meta_icon_globe"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
@ -95,7 +96,7 @@
</LinearLayout> </LinearLayout>
<Button <Button
android:id="@+id/fragment_settings_meta_contact_btn" android:id="@+id/settings_meta_button_contact"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="32sp" android:layout_marginTop="32sp"
@ -103,7 +104,7 @@
android:textAllCaps="false" /> android:textAllCaps="false" />
<Button <Button
android:id="@+id/fragment_settings_meta_donate_btn" android:id="@+id/settings_meta_button_donate"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/settings_meta_donate" android:text="@string/settings_meta_donate"

View file

@ -2,9 +2,8 @@
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:custom="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_settings_theme_container" android:id="@+id/settings_theme_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/colorPrimary" android:background="?attr/colorPrimary"
@ -16,6 +15,7 @@
tools:context=".settings.meta.SettingsFragmentMeta"> tools:context=".settings.meta.SettingsFragmentMeta">
<ScrollView <ScrollView
android:id="@+id/settings_theme_scroller"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
@ -25,6 +25,7 @@
android:orientation="vertical"> android:orientation="vertical">
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:id="@+id/settings_theme_finn"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="10sp" android:layout_marginBottom="10sp"
@ -35,6 +36,7 @@
android:layout_height="match_parent"> android:layout_height="match_parent">
<ImageView <ImageView
android:id="@+id/settings_theme_finn_img"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:adjustViewBounds="true" android:adjustViewBounds="true"
@ -43,7 +45,7 @@
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
<Button <Button
android:id="@+id/fragment_settings_theme_select_finn_btn" android:id="@+id/settings_theme_finn_button_select"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/settings_select_theme" android:text="@string/settings_select_theme"
@ -56,6 +58,7 @@
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:id="@+id/settings_theme_dark"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="10sp" android:layout_marginBottom="10sp"
@ -66,6 +69,7 @@
android:layout_height="match_parent"> android:layout_height="match_parent">
<ImageView <ImageView
android:id="@+id/settings_theme_dark_img"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:adjustViewBounds="true" android:adjustViewBounds="true"
@ -74,7 +78,7 @@
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
<Button <Button
android:id="@+id/fragment_settings_theme_select_dark_btn" android:id="@+id/settings_theme_dark_button_select"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/settings_select_theme" android:text="@string/settings_select_theme"
@ -86,6 +90,7 @@
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:id="@+id/settings_theme_custom"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="10sp" android:layout_marginBottom="10sp"
@ -96,7 +101,7 @@
android:layout_height="match_parent"> android:layout_height="match_parent">
<ImageView <ImageView
android:id="@+id/imageView" android:id="@+id/settings_theme_custom_img"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:adjustViewBounds="true" android:adjustViewBounds="true"
@ -105,7 +110,7 @@
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
<Button <Button
android:id="@+id/fragment_settings_theme_select_custom_btn" android:id="@+id/settings_theme_custom_button_select"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/settings_select_theme" android:text="@string/settings_select_theme"
@ -114,15 +119,15 @@
app:layout_constraintEnd_toEndOf="parent" /> app:layout_constraintEnd_toEndOf="parent" />
<Button <Button
android:id="@+id/fragment_settings_theme_custom_examples_btn" android:id="@+id/settings_theme_custom_button_examples"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/settings_theme_examples" android:text="@string/settings_theme_examples"
android:textAllCaps="false" android:textAllCaps="false"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/fragment_settings_theme_select_custom_btn" /> app:layout_constraintEnd_toStartOf="@id/settings_theme_custom_button_select" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>

View file

@ -1,9 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:custom="http://schemas.android.com/apk/res-auto" xmlns:custom="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_firststartup_container" android:id="@+id/tutorial_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/colorPrimary" android:background="?attr/colorPrimary"
@ -11,7 +12,7 @@
tools:context=".tutorial.TutorialActivity"> tools:context=".tutorial.TutorialActivity">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/activity_firststartup_app_bar" android:id="@+id/tutorial_appbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
@ -25,7 +26,7 @@
android:layout_height="match_parent"> android:layout_height="match_parent">
<TextView <TextView
android:id="@+id/activity_firststartup_heading" android:id="@+id/tutorial_heading"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
@ -37,15 +38,14 @@
custom:layout_constraintStart_toStartOf="parent" custom:layout_constraintStart_toStartOf="parent"
custom:layout_constraintTop_toTopOf="parent" /> custom:layout_constraintTop_toTopOf="parent" />
<com.finnmglas.launcher.extern.FontAwesome <com.finnmglas.launcher.libraries.FontAwesome
android:id="@+id/activity_firststartup_close" android:id="@+id/tutorial_close"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
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"
@ -60,7 +60,7 @@
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<TextView <TextView
android:id="@+id/activity_firststartup_section_heading" android:id="@+id/tutorial_page_heading"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
@ -73,7 +73,7 @@
app:layout_constraintVertical_bias="0.100000024" /> app:layout_constraintVertical_bias="0.100000024" />
<TextView <TextView
android:id="@+id/activity_firststartup_descriptive_text" android:id="@+id/tutorial_page_text"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginStart="32dp" android:layout_marginStart="32dp"
@ -89,10 +89,10 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.6" app:layout_constraintHorizontal_bias="0.6"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/activity_firststartup_section_heading" /> app:layout_constraintTop_toBottomOf="@id/tutorial_page_heading" />
<TextView <TextView
android:id="@+id/activity_firststartup_hint_text" android:id="@+id/tutorial_page_hint"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginStart="32dp" android:layout_marginStart="32dp"
@ -109,6 +109,6 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.6" app:layout_constraintHorizontal_bias="0.6"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/activity_firststartup_descriptive_text" /> app:layout_constraintTop_toBottomOf="@id/tutorial_page_text" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>