Skip to content

Commit

Permalink
Merge pull request #24 Improved Preference Screen from MrNegativeTW/p…
Browse files Browse the repository at this point in the history
…reference-screen

#6 Improved Preference Screen
  • Loading branch information
MrNegativeTW authored Oct 28, 2021
2 parents 9c9649b + 09e2ec3 commit 86080bc
Show file tree
Hide file tree
Showing 12 changed files with 257 additions and 108 deletions.
6 changes: 6 additions & 0 deletions course/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: "androidx.navigation.safeargs.kotlin"
apply plugin: 'com.mikepenz.aboutlibraries.plugin'

def apikeyPropertiesFile = rootProject.file("apikey.properties")
def apikeyProperties = new Properties()
Expand Down Expand Up @@ -50,6 +51,7 @@ dependencies {
kapt "androidx.room:room-compiler:$rootProject.roomVersion"
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.core:core-ktx:1.6.0'
implementation "androidx.fragment:fragment-ktx:1.3.5"
Expand Down Expand Up @@ -77,4 +79,8 @@ dependencies {

implementation 'com.github.chrisbanes:PhotoView:2.3.0'
implementation 'com.github.MikeOrtiz:TouchImageView:3.0.1'

implementation "com.mikepenz:aboutlibraries:${latestAboutLibsRelease}"
implementation "com.mikepenz:aboutlibraries-core:${latestAboutLibsRelease}"

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.txwstudio.app.timetable

import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Intent
import android.content.SharedPreferences
Expand Down Expand Up @@ -103,7 +104,13 @@ class HomeViewPagerFragment : Fragment() {
return true
}
R.id.menuSettings -> {
startActivity(Intent(requireContext(), PreferenceActivity::class.java))
val a = HomeViewPagerFragmentDirections.actionHomeViewPagerFragmentToPreferenceActivity()
findNavController().navigate(a)
/**
* Maybe use startActivityForResult
* {@link #getPrefValue}
* */
// startActivity(Intent(requireContext(), PreferenceActivity::class.java))
return true
}
else -> super.onOptionsItemSelected(item)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,57 +1,83 @@
package com.txwstudio.app.timetable.ui.activity

import android.os.Bundle
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.FragmentTransaction
import androidx.fragment.app.commit
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import com.txwstudio.app.timetable.R
import com.txwstudio.app.timetable.databinding.ActivityPreferenceBinding
import com.txwstudio.app.timetable.ui.preferences.PreferenceFragment

private const val TITLE_TAG = "settingsActivityTitle"

class PreferenceActivity : AppCompatActivity(),
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {

private lateinit var binding: ActivityPreferenceBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_preference)

setSupportActionBar(binding.toolbarSettingsAct)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}
binding.toolbarSettingsAct.setNavigationOnClickListener {
onBackPressed()
}

if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container_view, PreferenceFragment())
.commit()
} else {
title = savedInstanceState.getCharSequence(TITLE_TAG)
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
android.R.id.home -> {
finish()
true
supportFragmentManager.addOnBackStackChangedListener {
if (supportFragmentManager.backStackEntryCount == 0) {
setTitle(R.string.title_activity_settings)
}
else -> super.onOptionsItemSelected(item)
}
}

override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat?, pref: Preference): Boolean {
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
// Save current activity title so we can set it again after a configuration change
outState.putCharSequence(TITLE_TAG, title)
}

override fun onSupportNavigateUp(): Boolean {
if (supportFragmentManager.popBackStackImmediate()) {
return true
}
return super.onSupportNavigateUp()
}

override fun onPreferenceStartFragment(
caller: PreferenceFragmentCompat,
pref: Preference
): Boolean {
// Instantiate the new Fragment
val args = pref.extras
val fragment = supportFragmentManager.fragmentFactory.instantiate(
classLoader,
pref.fragment)
fragment.arguments = args
fragment.setTargetFragment(caller, 0)
classLoader,
pref.fragment
).apply {
arguments = args
// setTargetFragment(caller, 0) // deprecated in java
}

// Replace the existing Fragment with the new Fragment
supportFragmentManager.commit {
setCustomAnimations(
R.anim.fade_in,
R.anim.fade_out,
R.anim.fade_in,
R.anim.fade_out
)
setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
replace(R.id.fragment_container_view, fragment)
addToBackStack(null)
}
binding.appBarLayoutSettingsAct.setExpanded(true, true)
title = pref.title
return true
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.txwstudio.app.timetable.ui.preferences

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.ShortcutInfo
Expand All @@ -9,10 +10,11 @@ import android.graphics.drawable.Icon
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContract
import androidx.appcompat.app.AppCompatDelegate
import androidx.browser.customtabs.CustomTabsIntent
import androidx.preference.EditTextPreference
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager
Expand All @@ -27,8 +29,7 @@ private const val PREFERENCE_CALENDAR_PICKER = "pref_schoolCalendarPicker"
private const val PREFERENCE_MAP_CAL_HELPER = "pref_mapCalHelper"
const val PREFERENCE_WEEKEND_COL = "pref_weekendCol"
const val PREFERENCE_WEEKDAY_LENGTH_LONG = "pref_weekdayLengthLong"
private const val PREFERENCE_TEACHER_COL = "pref_teacherCol"
private const val PREFERENCE_CHANGELOG = "pref_changelog"
private const val PREFERENCE_BUG_REPORT = "pref_bugReport"

const val PREFERENCE_NAME_MAP_REQUEST = "schoolMapPath"
const val PREFERENCE_NAME_CALENDAR_REQUEST = "schoolCalendarPath"
Expand All @@ -40,15 +41,52 @@ private const val REQUEST_CODE_CALENDAR = 1
private const val BUG_REPORT_LINK = "http://bit.ly/timetableFeedback"

class PreferenceFragment : PreferenceFragmentCompat(),
Preference.OnPreferenceClickListener, SharedPreferences.OnSharedPreferenceChangeListener {
Preference.OnPreferenceClickListener, SharedPreferences.OnSharedPreferenceChangeListener {

private lateinit var prefManager: SharedPreferences
private lateinit var editTextPreference: EditTextPreference

override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
private val getMapContract = registerForActivityResult(MyContract()) { documentUri ->
if (documentUri == null) {
Toast.makeText(requireActivity(), R.string.fileReadErrorMsg, Toast.LENGTH_SHORT).show()
} else {
// Persist the permission across restarts.
requireActivity().contentResolver.takePersistableUriPermission(
documentUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION
)

// Save the document to [SharedPreferences].
prefManager.edit().putString(
PREFERENCE_NAME_MAP_REQUEST,
documentUri.toString()
).commit()
}
}

private val getCalendarContract = registerForActivityResult(MyContract()) { documentUri ->
if (documentUri == null) {
Toast.makeText(requireActivity(), R.string.fileReadErrorMsg, Toast.LENGTH_SHORT).show()
} else {
// Persist the permission across restarts.
requireActivity().contentResolver.takePersistableUriPermission(
documentUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION
)

createShortcut(documentUri)

// Save the document to [SharedPreferences].
prefManager.edit().putString(
PREFERENCE_NAME_CALENDAR_REQUEST,
documentUri.toString()
).commit()
}
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
prefManager = PreferenceManager.getDefaultSharedPreferences(requireContext())
setInitSummary()
// PreferenceManager.setDefaultValues(requireContext(), R.xml.preferences, false)
}

override fun onResume() {
Expand All @@ -63,6 +101,8 @@ class PreferenceFragment : PreferenceFragmentCompat(),

/**
* Handle file section, invoked by showPicker().
*
* @deprecated Switched to ActivityResultContract. Will be deleted soon.
* */
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
Expand All @@ -76,7 +116,7 @@ class PreferenceFragment : PreferenceFragmentCompat(),
}

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.preferences)
setPreferencesFromResource(R.xml.preferences, rootKey)
}

override fun onPreferenceClick(preference: Preference?): Boolean {
Expand All @@ -85,11 +125,10 @@ class PreferenceFragment : PreferenceFragmentCompat(),

override fun onPreferenceTreeClick(preference: Preference?): Boolean {
when (preference?.key) {
PREFERENCE_MAP_PICKER -> showPicker(REQUEST_CODE_MAP)
PREFERENCE_CALENDAR_PICKER -> showPicker(REQUEST_CODE_CALENDAR)
PREFERENCE_MAP_PICKER -> getMapContract.launch(REQUEST_CODE_MAP)
PREFERENCE_CALENDAR_PICKER -> getCalendarContract.launch(REQUEST_CODE_CALENDAR)
PREFERENCE_MAP_CAL_HELPER -> showDialog(PREFERENCE_MAP_CAL_HELPER)

"pref_bugReport" -> {
PREFERENCE_BUG_REPORT -> {
val customTabsIntent = CustomTabsIntent.Builder().build()
customTabsIntent.launchUrl(requireContext(), Uri.parse(BUG_REPORT_LINK))
}
Expand All @@ -99,30 +138,17 @@ class PreferenceFragment : PreferenceFragmentCompat(),

override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
when (key) {
PREFERENCE_TABLE_TITLE -> {
editTextPreference.summary =
sharedPreferences?.getString(PREFERENCE_TABLE_TITLE,
java.lang.String.valueOf(R.string.settings_timetableTitleSummary))
}
PREFERENCE_THEME -> {
val value = sharedPreferences?.getString(PREFERENCE_THEME, "-1")?.toInt()
AppCompatDelegate.setDefaultNightMode(value!!)
}
}
}

/**
* Set summary when open preference screen.
* */
private fun setInitSummary() {
editTextPreference = findPreference(PREFERENCE_TABLE_TITLE)!!

editTextPreference.summary = prefManager.getString(PREFERENCE_TABLE_TITLE,
getString(R.string.settings_timetableTitleDefaultValue))
}

/**
* Start an activity for picking file
*
* @deprecated Switched to ActivityResultContract. Will be deleted soon.
* */
private fun showPicker(requestCode: Int) {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
Expand Down Expand Up @@ -162,6 +188,8 @@ class PreferenceFragment : PreferenceFragmentCompat(),
*
* @param requestCode Receive code and decide which preference to write.
* @param data File uri
*
* @deprecated Switched to ActivityResultContract. Will be deleted soon.
*/
private fun handleSelectedFile(requestCode: Int, data: Intent) {
val prefName = when (requestCode) {
Expand All @@ -185,8 +213,6 @@ class PreferenceFragment : PreferenceFragmentCompat(),
requireActivity().contentResolver.takePersistableUriPermission(fileUri!!, takeFlags)
val filePath = fileUri.toString()

/**Old method, remove soon. */
// String filePath = Util.getPath(getContext(), fileUri);
val prefs = PreferenceManager.getDefaultSharedPreferences(requireContext())
val editor = prefs.edit()
editor.putString(prefName, filePath)
Expand All @@ -199,6 +225,8 @@ class PreferenceFragment : PreferenceFragmentCompat(),

/**
* Create shortcut it user set calendar path.
*
* @deprecated Switched to ActivityResultContract. Will be deleted soon.
* */
private fun createShortcut(data: Intent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
Expand All @@ -216,4 +244,50 @@ class PreferenceFragment : PreferenceFragmentCompat(),
shortcutManager.dynamicShortcuts = Arrays.asList(shortcut)
}
}

/**
* Create shortcut if user set calendar path.
*/
private fun createShortcut(documentUri: Uri) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
val shortcutManager = requireContext().getSystemService(ShortcutManager::class.java)
val shortcut = ShortcutInfo.Builder(context, "calendarShortcut")
.setShortLabel(getString(R.string.menuCalendar))
.setLongLabel(getString(R.string.menuCalendar))
.setIcon(Icon.createWithResource(context, R.mipmap.ic_event_note))
.setIntent(
Intent(Intent.ACTION_VIEW)
.setDataAndType(documentUri, "application/pdf")
.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
)
.build()
shortcutManager.dynamicShortcuts = listOf(shortcut)
}
}
}

/**
* For picking up file.
* */
class MyContract : ActivityResultContract<Int, Uri?>() {

override fun createIntent(context: Context, input: Int?): Intent {
return Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
type = when (input) {
REQUEST_CODE_MAP -> "image/*"
REQUEST_CODE_CALENDAR -> "application/pdf"
else -> "image/*"
}
putExtra(Intent.EXTRA_LOCAL_ONLY, true)
}
}

override fun parseResult(resultCode: Int, intent: Intent?): Uri? {
if (resultCode != Activity.RESULT_OK) {
return null
}
return intent?.data
}

}
Loading

0 comments on commit 86080bc

Please sign in to comment.