Initial push; upped AGP to 8.0.1, Kotlin plugin to 1.8.20, as well as updated all dependencies.

This commit is contained in:
denizk0461
2023-05-08 11:27:43 +02:00
commit 06ea1c88e4
113 changed files with 3055 additions and 0 deletions
@@ -0,0 +1,24 @@
package com.denizd.textbasic
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.denizd.textbasic", appContext.packageName)
}
}
+34
View File
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:backupAgent=".DriveAgent"
android:restoreAnyVersion="true">
<activity
android:name=".MainActivity"
android:exported="true"
android:windowSoftInputMode="adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".widget.TextCanvasWidget"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/appwidget_info" />
</receiver>
</application>
</manifest>
Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

@@ -0,0 +1,55 @@
package com.denizd.textbasic
import android.R
import java.util.*
import kotlin.math.roundToInt
/**
* Created by Hemant chand on 05/07/17.
*/
object ColorTransparentUtils {
// This default color int
const val defaultColorID = R.color.black
const val defaultColor = "000000"
const val TAG = "ColorTransparentUtils"
/**
* This method convert numver into hexa number or we can say transparent code
*
* @param trans number of transparency you want
* @return it return hex decimal number or transparency code
*/
fun convert(trans: Int): String {
val hexString = Integer.toHexString((255 * trans / 100.0).roundToInt())
return (if (hexString.length < 2) "0" else "") + hexString
}
fun transparentColor(colorCode: Int, trans: Int): String {
return convertIntoColor(colorCode, trans)
}
/**
* Convert color code into transparent color code
*
* @param colorCode color code
* @param transCode transparent number
* @return transparent color code
*/
fun convertIntoColor(colorCode: Int, transCode: Int): String {
// convert color code into hexa string and remove starting 2 digit
var color = defaultColor
try {
color = Integer.toHexString(colorCode).uppercase(Locale.getDefault()).substring(2)
} catch (ignored: Exception) {
}
return if (color.isNotEmpty() && transCode < 101) {
if (color.trim { it <= ' ' }.length == 6) {
"#" + convert(transCode) + color
} else {
// Log.d(TAG, "Color is already with transparency")
convert(transCode) + color
}
} else "#" + Integer.toHexString(defaultColorID).uppercase(Locale.getDefault()).substring(2)
// if color is empty or any other problem occur then we return deafult color;
}
}
@@ -0,0 +1,14 @@
package com.denizd.textbasic
import android.app.backup.*
class DriveAgent : BackupAgentHelper() {
override fun onCreate() {
super.onCreate()
SharedPreferencesBackupHelper(this, QuoteStorage.PREF_NAME).also {
addHelper(QuoteStorage.PREF_BACKUP_KEY, it)
}
}
}
@@ -0,0 +1,97 @@
package com.denizd.textbasic
import android.app.backup.BackupManager
import android.appwidget.AppWidgetManager
import android.content.ComponentName
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.Lifecycle
import com.denizd.textbasic.databinding.ActivityMainBinding
import com.denizd.textbasic.fragment.GuideFragment
import com.denizd.textbasic.fragment.QuoteFragment
import com.denizd.textbasic.fragment.SettingsFragment
import com.denizd.textbasic.widget.TextCanvasWidget
import com.google.android.material.snackbar.Snackbar
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(this.layoutInflater)
setContentView(binding.root)
// binding.buttonBackupDownload.setOnClickListener {
//
// Snackbar.make(binding.rootLayout, R.string.snack_backup_download, Snackbar.LENGTH_LONG).show()
// }
binding.buttonBackupUpload.setOnClickListener {
BackupManager(this).dataChanged()
Snackbar.make(binding.rootLayout, R.string.snack_backup_upload, Snackbar.LENGTH_LONG).show()
}
binding.bottomNav.setOnItemSelectedListener { item ->
loadFragment(item.itemId)
}
}
override fun onResume() {
super.onResume()
if (supportFragmentManager.fragments.size == 0) {
binding.bottomNav.selectedItemId = R.id.quotes
loadFragment(R.id.quotes)
}
}
private fun loadFragment(type: Int): Boolean {
val fragment = when (type) {
R.id.quotes -> QuoteFragment()
R.id.guide -> GuideFragment()
R.id.settings -> SettingsFragment()
else -> QuoteFragment()
}//supportFragmentManager.findFragmentByTag(type) ?: viewModel.getFragment(type)
if (supportFragmentManager.fragments.isNotEmpty() &&
supportFragmentManager.fragments[supportFragmentManager.fragments.size-1]
.tag?.equals(type.toString()) == true
) {
return false
}
if (fragment.lifecycle.currentState != Lifecycle.State.INITIALIZED) {
return false
}
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, fragment, type.toString())
// .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.commit()
// with (supportFragmentManager) {
// beginTransaction()
// .hide(fragments[fragments.size - 1]) // should this be 0?
// .show(findFragmentByTag(type) ?: TODO())
// .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
// .commit()
// }
return true
}
override fun onPause() {
arrayOf(TextCanvasWidget::class.java).forEach { widget ->
sendBroadcast(Intent(this, widget).also { intent ->
intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, AppWidgetManager.getInstance(this)
.getAppWidgetIds(ComponentName(application, widget)))
})
}
super.onPause()
}
}
@@ -0,0 +1,3 @@
package com.denizd.textbasic
data class Quote(val id: Int, var text: String)
@@ -0,0 +1,71 @@
package com.denizd.textbasic
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.button.MaterialButton
class QuoteAdapter(quotes: List<String>) : RecyclerView.Adapter<QuoteAdapter.QuoteViewHolder>() {
private var mutableQuotes: MutableList<String> = quotes.toMutableList()
class QuoteViewHolder(view: View) : RecyclerView.ViewHolder(view)/*, View.OnClickListener, View.OnLongClickListener*/ {
val quote: TextView = view.findViewById(R.id.quote)
val delete: ImageButton = view.findViewById(R.id.delete_button)
}
override fun getItemViewType(position: Int): Int {
return /*if (position == itemCount - 1) 1 else*/ 0
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QuoteViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.quote_entry, parent, false)
return QuoteViewHolder(v)
}
override fun onBindViewHolder(holder: QuoteViewHolder, position: Int) {
val currentItem = mutableQuotes[position]
holder.quote.text = currentItem
holder.quote.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun afterTextChanged(p0: Editable?) {}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
mutableQuotes[holder.layoutPosition] = p0.toString()
}
})
holder.delete.setOnClickListener {
mutableQuotes.removeAt(holder.layoutPosition)
notifyItemRemoved(holder.layoutPosition)
}
}
override fun getItemCount(): Int = mutableQuotes.size
fun setQuotes(quotes: List<String>) {
this.mutableQuotes = quotes.toMutableList()
notifyDataSetChanged()
}
fun addNewQuote() {
mutableQuotes.add("")
notifyItemInserted(mutableQuotes.size + 1)
}
fun getAllQuotes(): Array<String> {
return mutableQuotes.filter { s -> s.isNotBlank() }.toTypedArray()
}
interface QuoteClickListener {
fun onQuoteClick(quotes: String)
fun onQuoteLongClick(quoteId: Int)
}
}
@@ -0,0 +1,134 @@
package com.denizd.textbasic
import android.content.Context
import android.content.SharedPreferences
import android.graphics.Color
import android.graphics.Typeface
import android.util.Log
import androidx.preference.PreferenceManager
class QuoteStorage(context: Context) {
companion object {
const val PREF_NAME = "textbasicprefs"
const val PREF_BACKUP_KEY = "textbasicprefskey"
const val SEPARATOR = '\uFFFF'
private const val KEY_QUOTES = "quotes"
private const val KEY_QUOTE_COUNTER = "quotecounter"
private const val KEY_TEXT_SIZE = "textsize"
private const val KEY_INVERTED = "inverted"
private const val KEY_HIGH_CONTRAST = "hicontrast"
private const val KEY_TRANSPARENCY = "transparency"
private const val KEY_RANDOM = "random"
private const val KEY_WIDGET_POSITION = "widgetposition"
private const val KEY_BACKGROUND_TYPE = "backgroundtype"
private const val KEY_TYPEFACE = "typeface"
private const val KEY_TYPEFACE_STYLE = "typefacestyle"
private const val KEY_AVG_WIDTH = "avgwidth"
private const val KEY_AVG_HEIGHT = "avgheight"
private const val KEY_OUTLINE_SIZE = "outlinesize"
val prefGroups = arrayOf(
KEY_QUOTES, KEY_QUOTE_COUNTER, KEY_TEXT_SIZE, KEY_INVERTED, KEY_HIGH_CONTRAST,
KEY_TRANSPARENCY, KEY_RANDOM, KEY_WIDGET_POSITION
)
// val transparencyValues = arrayOf(
// "0", "5", "10", "15", "20", "25", "30", "35", "40", "45", "50",
// "55", "60", "65", "70", "75", "80", "85", "90", "95", "100",
// )
}
private val prefs = context.getSharedPreferences(PREF_NAME, 0)
fun getAllQuotes(): List<String> = ((prefs.getString(KEY_QUOTES, "")) ?: "").split(SEPARATOR).toList()
fun getRandomQuote(): String {
val quotes = getAllQuotes()
return quotes.random()
}
fun getNextQuote(): String {
val currentQuoteCounter: Int = prefs.getInt(KEY_QUOTE_COUNTER, 0)
val quotes = getAllQuotes()
val nextQuoteCounter: Int = if (currentQuoteCounter >= quotes.size - 1) 0 else currentQuoteCounter + 1
prefs.edit().putInt(
KEY_QUOTE_COUNTER,
nextQuoteCounter
).apply()
return quotes[nextQuoteCounter]
}
fun getTextSize() = prefs.getInt(KEY_TEXT_SIZE, 18)
fun isInvertedEnabled(): Boolean = prefs.getBoolean(KEY_INVERTED, false)
fun isHighContrastEnabled(): Boolean = prefs.getBoolean(KEY_HIGH_CONTRAST, false)
fun getTransparency(): Int = prefs.getInt(KEY_TRANSPARENCY, 100)
fun isOrderRandom(): Boolean = prefs.getBoolean(KEY_RANDOM, false)
fun getWidgetGravity(): Int = prefs.getInt(KEY_WIDGET_POSITION, 1)
fun getBackgroundType(): Int = prefs.getInt(KEY_BACKGROUND_TYPE, 0)
fun getTypefaceIndex(): Int = prefs.getInt(KEY_TYPEFACE, 0)
fun getTypeface(): Typeface = Typeface.create(
when (getTypefaceIndex()) {
1 -> Typeface.SERIF
2 -> Typeface.MONOSPACE
else -> Typeface.SANS_SERIF
},
getTypefaceStyle()
)
fun getTypefaceStyle(): Int = prefs.getInt(KEY_TYPEFACE_STYLE, 0)
fun getOutlineSize(): Float = prefs.getFloat(KEY_OUTLINE_SIZE, 8f)
// Pair<text colour, background colour>
fun getColours(
isInverted: Boolean = isInvertedEnabled(),
transparency: Int = getTransparency(),
context: Context
): Pair<Int, Int> {
val colours = when (isInverted) {
true -> Pair(R.color.widget_dark, R.color.widget_light)
false -> Pair(R.color.widget_light, R.color.widget_dark)
}
return Pair(
context.getColor(colours.first),//Color.parseColor(ColorTransparentUtils.transparentColor(colours.first, 10)),
Color.parseColor(ColorTransparentUtils.transparentColor(context.getColor(colours.second), transparency * 5))
)
}
fun setSize(size: Pair<Int, Int>) {
prefs.edit().apply {
putInt(KEY_AVG_WIDTH, size.first)
putInt(KEY_AVG_HEIGHT, size.second)
}.apply()
}
fun getSize(): Pair<Int, Int> = Pair(prefs.getInt(KEY_AVG_WIDTH, 1), prefs.getInt(KEY_AVG_HEIGHT, 1))
fun saveSettings(
textSize: Int, inverted: Boolean, transparency: Int, random: Boolean,
widgetPosition: Int, backgroundType: Int, typefaceIndex: Int, typefaceStyleIndex: Int,
outlineSize: Float
) {
prefs.edit().apply {
putInt(KEY_TEXT_SIZE, textSize)
putBoolean(KEY_INVERTED, inverted)
putInt(KEY_TRANSPARENCY, transparency)
putBoolean(KEY_RANDOM, random)
putInt(KEY_WIDGET_POSITION, widgetPosition)
putInt(KEY_BACKGROUND_TYPE, backgroundType)
putInt(KEY_TYPEFACE, typefaceIndex)
putInt(KEY_TYPEFACE_STYLE, typefaceStyleIndex)
putFloat(KEY_OUTLINE_SIZE, outlineSize)
}.apply()
}
fun saveQuotes(quotes: Array<String>) {
prefs.edit()
.putString(KEY_QUOTES, quotes.joinToString(SEPARATOR.toString()))
.apply()
}
}
@@ -0,0 +1,71 @@
package com.denizd.textbasic
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.Context
import android.content.Intent
import android.graphics.Typeface
import android.util.TypedValue
import android.view.Gravity
import android.widget.RemoteViews
import android.widget.TextView
class TextWidget : AppWidgetProvider() {
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
val remoteViews = configureViews(context, appWidgetIds)
// Perform this loop procedure for each App Widget that belongs to this provider
appWidgetIds.forEach { appWidgetId ->
// Tell the AppWidgetManager to perform an update on the current app widget
appWidgetManager.updateAppWidget(appWidgetId, remoteViews)
}
}
private fun configureViews(context: Context, appWidgetIds: IntArray): RemoteViews =
RemoteViews(context.packageName, R.layout.widget_text).apply {
val storage = QuoteStorage(context)
val quote = if (storage.isOrderRandom()) {
storage.getRandomQuote()
} else {
storage.getNextQuote()
}
setTextViewText(R.id.widget_text, quote.ifBlank { context.getString(R.string.info_add_text) })
setTextViewTextSize(R.id.widget_text, TypedValue.COMPLEX_UNIT_SP, storage.getTextSize().toFloat())
val colours = storage.getColours(context = context)
setTextColor(R.id.widget_text, colours.first)
setInt(R.id.background, "setBackgroundColor", colours.second)
val gravity = when (storage.getWidgetGravity()) {
0 -> Gravity.START or Gravity.TOP
1 -> Gravity.CENTER_HORIZONTAL or Gravity.TOP
2 -> Gravity.END or Gravity.TOP
3 -> Gravity.START or Gravity.CENTER_VERTICAL
4 -> Gravity.CENTER
5 -> Gravity.END or Gravity.CENTER_VERTICAL
6 -> Gravity.START or Gravity.BOTTOM
7 -> Gravity.CENTER_HORIZONTAL or Gravity.BOTTOM
8 -> Gravity.END or Gravity.BOTTOM
else -> Gravity.CENTER
}
setInt(R.id.root_layout, "setGravity", gravity)
setOnClickPendingIntent(
R.id.root_layout,
Intent(context, TextWidget::class.java).let { intent ->
intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds)
PendingIntent.getBroadcast(
context, 0, intent, PendingIntent.FLAG_IMMUTABLE
)
}
)
}
}
@@ -0,0 +1,41 @@
package com.denizd.textbasic
import android.content.Context
import android.graphics.Canvas
import android.graphics.Rect
import android.util.AttributeSet
class VerticalTextView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0
) : androidx.appcompat.widget.AppCompatTextView(context, attrs, defStyle) {
private var _width = 0
private var _height = 0
private val _bounds: Rect = Rect()
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
// vise versa
_height = measuredWidth
_width = measuredHeight
setMeasuredDimension(_width, _height)
}
override fun onDraw(canvas: Canvas) {
canvas.save()
canvas.translate(_width.toFloat(), _height.toFloat())
canvas.rotate(-90f)
val paint = paint
paint.color = textColors.defaultColor
val text = text()
paint.getTextBounds(text, 0, text.length, _bounds)
canvas.drawText(text, compoundPaddingLeft.toFloat(), (_bounds.height() - _width) / 2f, paint)
canvas.restore()
}
private fun text(): String {
return super.getText().toString()
}
}
@@ -0,0 +1,39 @@
package com.denizd.textbasic.fragment
import android.content.Context
import androidx.annotation.LayoutRes
import androidx.core.widget.NestedScrollView
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView
open class BaseFragment(@LayoutRes layoutId: Int) : Fragment(layoutId) {
private lateinit var _context: Context
override fun onAttach(context: Context) {
super.onAttach(context)
_context = context
}
override fun getContext(): Context = _context
// protected fun RecyclerView.addFabScrollListener() {
// addOnScrollListener(object : RecyclerView.OnScrollListener() {
// override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
// when {
// dy > 0 -> fab.hide()
// dy < 0 -> fab.show()
// }
// }
// })
// }
//
// protected fun NestedScrollView.addFabScrollListener() {
// setOnScrollChangeListener { _, _, dy, _, doy ->
// when {
// dy > doy -> fab.hide()
// dy < doy -> fab.show()
// }
// }
// }
}
@@ -0,0 +1,18 @@
package com.denizd.textbasic.fragment
import android.os.Bundle
import com.denizd.textbasic.R
import com.google.android.material.transition.MaterialSharedAxis
class GuideFragment : BaseFragment(R.layout.fragment_guide) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
}
}
@@ -0,0 +1,57 @@
package com.denizd.textbasic.fragment
import android.animation.LayoutTransition
import android.os.Bundle
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import com.denizd.textbasic.QuoteAdapter
import com.denizd.textbasic.QuoteStorage
import com.denizd.textbasic.util.viewBinding
import com.denizd.textbasic.R
import com.denizd.textbasic.databinding.FragmentQuoteBinding
import com.google.android.material.transition.MaterialSharedAxis
class QuoteFragment : BaseFragment(R.layout.fragment_quote) {
private lateinit var storage: QuoteStorage
private lateinit var quoteAdapter: QuoteAdapter
private val binding: FragmentQuoteBinding by viewBinding(FragmentQuoteBinding::bind)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.quoteConstraintLayout.layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
storage = QuoteStorage(context)
quoteAdapter = QuoteAdapter(storage.getAllQuotes())
binding.quoteScroller.let { s ->
s.layoutManager = LinearLayoutManager(context)
s.adapter = quoteAdapter
}
binding.addFab.setOnClickListener {
quoteAdapter.addNewQuote()
}
}
private fun save() {
storage.saveQuotes(quoteAdapter.getAllQuotes())
}
override fun onPause() {
save()
super.onPause()
}
}
@@ -0,0 +1,319 @@
package com.denizd.textbasic.fragment
import android.graphics.Bitmap
import android.graphics.Color
import android.os.Bundle
import android.util.Log
import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.annotation.ColorInt
import com.denizd.textbasic.ColorTransparentUtils
import com.denizd.textbasic.QuoteStorage
import com.denizd.textbasic.R
import com.denizd.textbasic.databinding.FragmentSettingsBinding
import com.denizd.textbasic.util.viewBinding
import com.denizd.textbasic.widget.CanvasText
import com.google.android.material.transition.MaterialSharedAxis
import java.lang.reflect.Field
import kotlin.math.abs
class SettingsFragment : BaseFragment(R.layout.fragment_settings) {
private lateinit var storage: QuoteStorage
private lateinit var gravityButtons: Array<ImageButton>
private var widgetGravity = 4
private var backgroundIndex = 0
private var typefaceIndex = 0
private var typefaceStyleIndex = 0
private val binding: FragmentSettingsBinding by viewBinding(FragmentSettingsBinding::bind)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// binding.animationLl.animateLayoutChanges(true)
storage = QuoteStorage(context)
gravityButtons = arrayOf(
binding.buttonTopLeft, binding.buttonTopMiddle, binding.buttonTopRight,
binding.buttonMiddleLeft, binding.buttonMiddleMiddle, binding.buttonMiddleRight,
binding.buttonBottomLeft, binding.buttonBottomMiddle, binding.buttonBottomRight
)
widgetGravity = storage.getWidgetGravity()
binding.textSizePicker.apply {
minValue = 1
maxValue = 168
descendantFocusability = ViewGroup.FOCUS_BLOCK_DESCENDANTS
wrapSelectorWheel = false
value = storage.getTextSize()
setOnValueChangedListener { _, _, _ ->
updatePreview()
}
}
binding.transparencyPicker.apply {
minValue = 0
maxValue = 20
val formatter = NumberPicker.Formatter { value ->
val temp = value * 5
"" + temp
}
setFormatter(formatter)
descendantFocusability = ViewGroup.FOCUS_BLOCK_DESCENDANTS
wrapSelectorWheel = false
value = storage.getTransparency()
// Do not touch - fix for value on spinner not showing up until touched
val f: Field = NumberPicker::class.java.getDeclaredField("mInputText")
f.isAccessible = true
val inputText: EditText = f.get(binding.transparencyPicker) as EditText
inputText.filters = arrayOfNulls(0)
setOnValueChangedListener { _, _, _ ->
updatePreview()
}
}
binding.outlinePicker.apply {
minValue = 0
maxValue = 64
descendantFocusability = ViewGroup.FOCUS_BLOCK_DESCENDANTS
wrapSelectorWheel = false
value = storage.getOutlineSize().toInt()
setOnValueChangedListener { _, _, _ ->
updatePreview()
}
}
binding.switchInvert.apply {
isChecked = storage.isInvertedEnabled()
setOnCheckedChangeListener { _, _ ->
updatePreview()
}
}
binding.switchRandom.apply {
isChecked = storage.isOrderRandom()
setOnCheckedChangeListener { _, _ ->
updatePreview()
}
}
// binding.switchHighContrast.apply {
// isChecked = storage.isHighContrastEnabled()
//
// setOnCheckedChangeListener { _, _ ->
// updatePreview()
// }
// }
// binding.typefaceMenuTextview.apply {
// typefaceIndex = storage.getTypefaceIndex()
// val typefaces = context.resources.getStringArray(R.array.typefaces)
// val typefaceAdapter = ArrayAdapter(
// context,
// android.R.layout.simple_dropdown_item_1line,
// typefaces
// )
// setAdapter(typefaceAdapter)
// setText(typefaces[typefaceIndex], false)
//
// setOnItemClickListener { adapterView, view, index, l ->
// typefaceIndex = index
// updatePreview()
// }
// }
binding.typefaceToggleButton.apply {
typefaceIndex = storage.getTypefaceIndex()
check(when (typefaceStyleIndex) {
2 -> R.id.button3_monospace
1 -> R.id.button2_serif
else -> R.id.button1_sansserif
})
addOnButtonCheckedListener { group, checkedId, isChecked ->
typefaceIndex = when (checkedId) {
R.id.button3_monospace -> 2
R.id.button2_serif -> 1
else -> 0
}
updatePreview()
}
}
binding.typefaceStyleToggleButton.apply {
typefaceStyleIndex = storage.getTypefaceStyle()
check(when (typefaceStyleIndex) {
3 -> R.id.button4_bold_italics
2 -> R.id.button3_italics
1 -> R.id.button2_bold
else -> R.id.button1_normal
})
addOnButtonCheckedListener { group, checkedId, isChecked ->
typefaceStyleIndex = when (checkedId) {
R.id.button4_bold_italics -> 3
R.id.button3_italics -> 2
R.id.button2_bold -> 1
else -> 0
}
updatePreview()
}
}
binding.backgroundToggleButton.apply {
backgroundIndex = storage.getBackgroundType()
check(when (backgroundIndex) {
2 -> R.id.button3_shadow
1 -> R.id.button2_outline
else -> R.id.button1_background
})
addOnButtonCheckedListener { group, checkedId, isChecked ->
backgroundIndex = when (checkedId) {
R.id.button3_shadow -> 2
R.id.button2_outline -> 1
else -> 0
}
updatePreview()
}
}
gravityButtons.forEachIndexed { index, button ->
button.setOnClickListener {
widgetGravity = index
setGravityButtons()
updatePreview()
}
}
setGravityButtons()
updatePreview()
}
private fun setGravityButtons() {
val transparent = context.getColor(android.R.color.transparent)
gravityButtons.forEach { button ->
button.setBackgroundColor(transparent)
}
val typedValue = TypedValue()
context.theme.resolveAttribute(R.attr.colorSecContainer, typedValue, true)
@ColorInt val colorTertiary = typedValue.data
gravityButtons[widgetGravity].setBackgroundColor(colorTertiary)
}
private fun updatePreview() {
save()
if (backgroundIndex == 0) {
binding.outlineTextview.visibility = View.GONE
binding.outlinePicker.visibility = View.GONE
} else {
binding.outlineTextview.visibility = View.VISIBLE
binding.outlinePicker.visibility = View.VISIBLE
if (backgroundIndex == 1) {
binding.outlineTextview.text = getString(R.string.thickness)
} else {
binding.outlineTextview.text = getString(R.string.intensity)
}
}
// val isBackgroundDark = if (storage.isInvertedEnabled()) { // bg white
// (storage.getTransparency() * 5) <= 5
// } else { // bg black
// (storage.getTransparency() * 5) > 5
// }
// Log.d("ASDF", isBackgroundDark.toString())
// binding.textPreviewBackground.setBackgroundColor(
// Color.parseColor(ColorTransparentUtils.transparentColor(context.getColor(if (isBackgroundDark) {
// R.color.md_theme_light_background
// } else {
// R.color.md_theme_dark_background
// }), storage.getTransparency() * 5)))
// binding.textPreviewBackground.setBackgroundColor(
// storage.getColours(
// !storage.isInvertedEnabled(),
// abs(storage.getTransparency() - 100),
// context = context
// ).second
// )
binding.textPreviewBackgroundDark.setBackgroundColor(
Color.parseColor(ColorTransparentUtils.transparentColor(
context.getColor(R.color.md_theme_dark_background),
if (storage.isInvertedEnabled()) {
abs((storage.getTransparency() * 5))
} else {
abs((storage.getTransparency() * 5) - 100)
}
))
)
val bitmap = CanvasText.drawText(context, true)
binding.textPreview.setImageBitmap(bitmap)
// val colours = storage.getColours(
// binding.switchInvert.isChecked,
//// binding.switchHighContrast.isChecked,
// binding.transparencyPicker.value,
// context
// )
//// binding.exampleText.textSize = binding.textSizePicker.value.toFloat()
// binding.exampleText.setTextColor(colours.first)
// binding.background.setBackgroundColor(colours.second)
// Log.d("VALVALUE", "${(binding.transparencyPicker.value * 5).toString()} /// ${colours.second}")
}
private fun save() {
storage.saveSettings(
binding.textSizePicker.value,
binding.switchInvert.isChecked,
// binding.switchHighContrast.isChecked,
binding.transparencyPicker.value,
binding.switchRandom.isChecked,
widgetGravity,
backgroundIndex,
typefaceIndex,
typefaceStyleIndex,
binding.outlinePicker.value.toFloat()
)
}
override fun onPause() {
save()
super.onPause()
}
}
@@ -0,0 +1,12 @@
package com.denizd.textbasic.util
import android.view.LayoutInflater
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentActivity
import androidx.viewbinding.ViewBinding
// written by Zhuinden (props to them!)
inline fun <T : ViewBinding> FragmentActivity.viewBinding(crossinline bindingInflater: (LayoutInflater) -> T) =
lazy(LazyThreadSafetyMode.NONE) {
bindingInflater.invoke(layoutInflater)
}
@@ -0,0 +1,50 @@
package com.denizd.textbasic.util
import android.view.View
import androidx.fragment.app.Fragment
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.observe
import androidx.viewbinding.ViewBinding
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
// written by Zhuinden (props to them!)
class FragmentViewBindingDelegate<T : ViewBinding>(
val fragment: Fragment,
val viewBindingFactory: (View) -> T
) : ReadOnlyProperty<Fragment, T> {
private var _binding: T? = null
init {
fragment.lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onCreate(owner: LifecycleOwner) {
fragment.viewLifecycleOwnerLiveData.observe(fragment) { viewLifecycleOwner ->
viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onDestroy(owner: LifecycleOwner) {
_binding = null
}
})
}
}
})
}
override fun getValue(thisRef: Fragment, property: KProperty<*>): T {
val binding = _binding
if (binding != null) {
return binding
}
val lifecycle = fragment.viewLifecycleOwner.lifecycle
if (!lifecycle.currentState.isAtLeast(Lifecycle.State.INITIALIZED)) {
throw IllegalStateException("Should not attempt to get bindings when Fragment views are destroyed.")
}
return viewBindingFactory(thisRef.requireView()).also { _binding = it }
}
}
fun <T : ViewBinding> Fragment.viewBinding(viewBindingFactory: (View) -> T) =
FragmentViewBindingDelegate(this, viewBindingFactory)
@@ -0,0 +1,268 @@
package com.denizd.textbasic.widget
import android.content.Context
import android.graphics.*
import android.text.StaticLayout
import android.text.TextPaint
import android.util.Log
import com.denizd.textbasic.QuoteStorage
import com.denizd.textbasic.R
class CanvasText {
companion object {
fun drawText(context: Context, isPreview: Boolean = false, size: Pair<Int, Int>? = null): Bitmap {
val previewSize = 20f
val storage = QuoteStorage(context)
size?.let {
storage.setSize(size)
// Log.d("ASDF", "${size.first} + ${size.second}")
}
val widgetSize = storage.getSize()
val outlineSize = storage.getOutlineSize()
val bmp = if (isPreview) {
Bitmap.createBitmap(1024, 256, Bitmap.Config.ARGB_8888)
} else {
// Log.d("ASDFasdf", "${widgetSize.first} + ${widgetSize.second}")
Bitmap.createBitmap(widgetSize.first * 3, widgetSize.second * 3, Bitmap.Config.ARGB_8888)
}
val canvas = Canvas(bmp)
val quote = if (isPreview) {
context.getString(R.string.example_text)
} else if (storage.isOrderRandom()) {
storage.getRandomQuote()
} else {
storage.getNextQuote()
}.ifBlank { context.getString(R.string.info_add_text) }
val colours = storage.getColours(context = context)
val scaledTextSize =
context.resources.displayMetrics.scaledDensity * if (/*isPreview*/false) previewSize else {
storage.getTextSize().toFloat()
}
val savedTypeface = storage.getTypeface()
val widgetGravity = storage.getWidgetGravity()
val paint = TextPaint().apply {
style = Paint.Style.FILL
color = colours.first
textSize = scaledTextSize
textAlign = when (widgetGravity) {
0, 3, 6 -> Paint.Align.LEFT
2, 5, 8 -> Paint.Align.RIGHT
else -> Paint.Align.CENTER
}
isAntiAlias = true
isSubpixelText = false
typeface = savedTypeface
}
val staticLayout = StaticLayout.Builder
.obtain(quote, 0, quote.length, paint, if (isPreview) 1024 else widgetSize.first * 3).build()
val boundsText = Rect()
paint.getTextBounds(quote, 0, quote.length, boundsText)
val (x, y) = calculateWidgetGravity(storage.getWidgetGravity(), bmp, boundsText, isPreview)
// val x = canvas.width / 2
// val y = ((canvas.getHeight() / 2) - ((paint.descent() + paint.ascent()) / 2))
val padding = 16f
val alignment = when (widgetGravity) {
0 -> {
canvas.translate(boundsText.left.toFloat() + padding, 0f)
Paint.Align.LEFT
}
1 -> {
canvas.translate(canvas.width / 2f, 0f)
Paint.Align.CENTER
}
2 -> {
canvas.translate(canvas.width.toFloat() - padding, 0f)
Paint.Align.RIGHT
}
3 -> {
canvas.translate(boundsText.left.toFloat() + padding, 0f)
Paint.Align.LEFT
}
5 -> {
canvas.translate(canvas.width.toFloat() - padding, 0f)
Paint.Align.RIGHT
}
6 -> {
canvas.translate(boundsText.left.toFloat() + padding, bmp.height.toFloat() - staticLayout.height - padding)
Paint.Align.LEFT
}
7 -> {
canvas.translate(canvas.width / 2f, bmp.height.toFloat() - staticLayout.height - padding)
Paint.Align.CENTER
}
8 -> {
canvas.translate(canvas.width.toFloat() - padding, bmp.height.toFloat() - staticLayout.height - padding)
Paint.Align.RIGHT
}
else -> { // 4
canvas.translate(canvas.width / 2f, 0f)
Paint.Align.CENTER
}
}
when (val bgType = storage.getBackgroundType()) {
0 -> { // background
val bgPaint = Paint().apply {
style = Paint.Style.FILL
color = colours.second
}
val rounding = 24f
// val rect = roundedRect(
// boundsText.left + x - padding,
// boundsText.top + y - padding,
// boundsText.right + x + padding,
// boundsText.bottom + y + padding, rounding, rounding
// )
// val rect = roundedRect(
// 0f, 0f, boundsText.right.toFloat() / 2, staticLayout.height.toFloat(),
// rounding, rounding
// )
val rect = when (widgetGravity) { // right
2, 5, 8 -> roundedRect(
-boundsText.right.toFloat() - 4f, 0f, 0f, staticLayout.height.toFloat(),
rounding, rounding
)
1, 4, 7 -> roundedRect( // middle
-(boundsText.width() / 2f), 0f,
boundsText.right.toFloat() / 2f, staticLayout.height.toFloat(),
rounding, rounding
)
else -> roundedRect( // left
0f, 0f, boundsText.right.toFloat() + 4f, staticLayout.height.toFloat(),
rounding, rounding
)
}
canvas.drawPath(rect, bgPaint)
}
1, 2 -> { // outline or shadow
val strokePaint = TextPaint().apply {
style = Paint.Style.STROKE
strokeWidth = outlineSize //if (isPreview) previewSize / 1.5f else
color = colours.second
textSize = scaledTextSize
textAlign = alignment
isAntiAlias = true
isSubpixelText = false
typeface = savedTypeface
if (bgType == 2) { // blur outline for shadow
maskFilter = BlurMaskFilter(if (outlineSize == 0f) 1f else outlineSize, BlurMaskFilter.Blur.NORMAL)
}
}
val strokeStaticLayout = StaticLayout.Builder
.obtain(quote, 0, quote.length, strokePaint, if (isPreview) 1024 else widgetSize.first * 3).build()
strokeStaticLayout.draw(canvas)
// canvas.drawText(quote, x, y, strokePaint)
}
}
staticLayout.draw(canvas)
// canvas.drawText(quote, x, y, paint)
return bmp
}
private fun calculateWidgetGravity(widgetGravity: Int, bitmap: Bitmap, boundsText: Rect, isPreview: Boolean) : Pair<Float, Float> {
return if (isPreview) {
Pair((bitmap.width - boundsText.width()) / 2f, (bitmap.height + boundsText.height()) / 2f)
} else when (widgetGravity) {
0 -> { // top left
Pair(0f + boundsText.left, (boundsText.height() - boundsText.top).toFloat())
}
1 -> { // top center
Pair(
(bitmap.width - boundsText.width()) / 2f,
(boundsText.height() - boundsText.top).toFloat()
)
}
2 -> { // top right
Pair(
(bitmap.width - (boundsText.right)).toFloat(),
(boundsText.height() - boundsText.top).toFloat()
)
}
3 -> { // center left
Pair(0f + boundsText.left, (bitmap.height + boundsText.height()) / 2f)
}
// 4 == else branch
5 -> { // center right
Pair(
(bitmap.width - (boundsText.right)).toFloat(),
(bitmap.height + boundsText.height()) / 2f
)
}
6 -> { // bottom left
Pair(0f + boundsText.left, (bitmap.height - boundsText.bottom).toFloat())
}
7 -> { // bottom center
Pair(
(bitmap.width - boundsText.width()) / 2f,
(bitmap.height - boundsText.bottom).toFloat()
)
}
8 -> { // bottom right
Pair(
(bitmap.width - (boundsText.right)).toFloat(),
(bitmap.height - boundsText.bottom).toFloat()
)
}
else -> { // center center LIKE 4
Pair(
(bitmap.width - boundsText.width()) / 2f,
(bitmap.height + boundsText.height()) / 2f
)
}
}
}
fun roundedRect(
left: Float, top: Float, right: Float, bottom: Float,
roundingX: Float, roundingY: Float
): Path {
var rx = roundingX
var ry = roundingY
val path = Path()
if (rx < 0) rx = 0f
if (ry < 0) ry = 0f
val width = right - left
val height = bottom - top
if (rx > width / 2) rx = width / 2
if (ry > height / 2) ry = height / 2
val widthMinusCorners = width - 2 * rx
val heightMinusCorners = height - 2 * ry
path.moveTo(right, top + ry)
path.rQuadTo(0f, -ry, -rx, -ry) //top-right corner
path.rLineTo(-widthMinusCorners, 0f)
path.rQuadTo(-rx, 0f, -rx, ry) //top-left corner
path.rLineTo(0f, heightMinusCorners)
path.rQuadTo(0f, ry, rx, ry) //bottom-left corner
path.rLineTo(widthMinusCorners, 0f)
path.rQuadTo(rx, 0f, rx, -ry) //bottom-right corner
path.rLineTo(0f, -heightMinusCorners)
path.close() //Given close, last lineto can be removed.
return path
}
}
}
@@ -0,0 +1,68 @@
package com.denizd.textbasic.widget
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.graphics.*
import android.os.Bundle
import android.util.Log
import android.widget.RemoteViews
import com.denizd.textbasic.R
import kotlin.random.Random
class TextCanvasWidget : AppWidgetProvider() {
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
// Perform this loop procedure for each App Widget that belongs to this provider
appWidgetIds.forEach { appWidgetId ->
val remoteViews = configureViews(context, appWidgetIds)
// Tell the AppWidgetManager to perform an update on the current app widget
appWidgetManager.updateAppWidget(appWidgetId, remoteViews)
}
}
private fun configureViews(context: Context, appWidgetIds: IntArray, size: Pair<Int, Int>? = null): RemoteViews =
RemoteViews(context.packageName, R.layout.widget_bitmap).apply {
val bitmap = CanvasText.drawText(context, size = size)
setImageViewBitmap(R.id.bitmap_view, bitmap)
setOnClickPendingIntent(
R.id.bmp_root_layout,
Intent(context, TextCanvasWidget::class.java).let { intent ->
intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds)
PendingIntent.getBroadcast(
context, Random.nextInt(), intent, PendingIntent.FLAG_IMMUTABLE
)
}
)
}
override fun onAppWidgetOptionsChanged(
context: Context?,
appWidgetManager: AppWidgetManager?,
appWidgetId: Int,
newOptions: Bundle?
) {
super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions)
val width = (newOptions?.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH) ?: 0)
val height = (newOptions?.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT) ?: 0)
// Log.d("ASDFF", (newOptions?.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH)).toString())
context?.let {
val remoteViews = configureViews(context, intArrayOf(appWidgetId), Pair(width, height))
// Tell the AppWidgetManager to perform an update on the current app widget
appWidgetManager?.updateAppWidget(appWidgetId, remoteViews)
}
}
}
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:color="?attr/colorOnPrimary" />
<!-- <item android:state_checked="false" android:color="?attr/colorOnSecondarySoft" />-->
</selector>
<!--second one should be hint!-->
+10
View File
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</vector>
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M19,15l-1.41,-1.41L13,18.17V2H11v16.17l-4.59,-4.59L5,15l7,7L19,15z"/>
</vector>
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M15,19v-2H8.41L20,5.41L18.59,4L7,15.59V9H5v10H15z"/>
</vector>
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M19,9h-2v6.59L5.41,4L4,5.41L15.59,17H9v2h10V9z"/>
</vector>
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M16.59,8.59L12,13.17 7.41,8.59 6,10l6,6 6,-6z"/>
</vector>
+10
View File
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M9,19l1.41,-1.41L5.83,13H22V11H5.83l4.59,-4.59L9,5l-7,7L9,19z"/>
</vector>
+10
View File
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M15,5l-1.41,1.41L18.17,11H2V13h16.17l-4.59,4.59L15,19l7,-7L15,5z"/>
</vector>
+10
View File
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M5,9l1.41,1.41L11,5.83V22H13V5.83l4.59,4.59L19,9l-7,-7L5,9z"/>
</vector>
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M5,15h2V8.41L18.59,20L20,18.59L8.41,7H15V5H5V15z"/>
</vector>
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M9,5v2h6.59L4,18.59L5.41,20L17,8.41V15h2V5H9z"/>
</vector>
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,8l-6,6 1.41,1.41L12,10.83l4.59,4.58L18,14z"/>
</vector>
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M18,2L6,2c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,4c0,-1.1 -0.9,-2 -2,-2zM9,4h2v5l-1,-0.75L9,9L9,4zM18,20L6,20L6,4h1v9l3,-2.25L13,13L13,4h5v16z"/>
</vector>
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96zM17,13l-5,5 -5,-5h3V9h4v4h3z"/>
</vector>
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96zM14,13v4h-4v-4H7l5,-5 5,5h-3z"/>
</vector>
+10
View File
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2L18,7L6,7v12zM8,9h8v10L8,19L8,9zM15.5,4l-1,-1h-5l-1,1L5,4v2h14L19,4z"/>
</vector>
+13
View File
@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<!-- <path-->
<!-- android:fillColor="@android:color/white"-->
<!-- android:pathData="M15.54,5.54L13.77,7.3 12,5.54 10.23,7.3 8.46,5.54 12,2zM18.46,15.54l-1.76,-1.77L18.46,12l-1.76,-1.77 1.76,-1.77L22,12zM8.46,18.46l1.77,-1.76L12,18.46l1.77,-1.76 1.77,1.76L12,22zM5.54,8.46l1.76,1.77L5.54,12l1.76,1.77 -1.76,1.77L2,12z"/>-->
<path
android:fillColor="@android:color/white"
android:pathData="M12,12m-3,0a3,3 0,1 1,6 0a3,3 0,1 1,-6 0"/>
</vector>
Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

@@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#000000"/>
<corners android:radius="12dp"/>
<padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
</shape>
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM5.92,19H5v-0.92l9.06,-9.06 0.92,0.92L5.92,19zM20.71,5.63l-2.34,-2.34c-0.2,-0.2 -0.45,-0.29 -0.71,-0.29s-0.51,0.1 -0.7,0.29l-1.83,1.83 3.75,3.75 1.83,-1.83c0.39,-0.39 0.39,-1.02 0,-1.41z"/>
</vector>
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98 0,-0.34 -0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.09,-0.16 -0.26,-0.25 -0.44,-0.25 -0.06,0 -0.12,0.01 -0.17,0.03l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.06,-0.02 -0.12,-0.03 -0.18,-0.03 -0.17,0 -0.34,0.09 -0.43,0.25l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98 0,0.33 0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.09,0.16 0.26,0.25 0.44,0.25 0.06,0 0.12,-0.01 0.17,-0.03l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.06,0.02 0.12,0.03 0.18,0.03 0.17,0 0.34,-0.09 0.43,-0.25l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM17.45,11.27c0.04,0.31 0.05,0.52 0.05,0.73 0,0.21 -0.02,0.43 -0.05,0.73l-0.14,1.13 0.89,0.7 1.08,0.84 -0.7,1.21 -1.27,-0.51 -1.04,-0.42 -0.9,0.68c-0.43,0.32 -0.84,0.56 -1.25,0.73l-1.06,0.43 -0.16,1.13 -0.2,1.35h-1.4l-0.19,-1.35 -0.16,-1.13 -1.06,-0.43c-0.43,-0.18 -0.83,-0.41 -1.23,-0.71l-0.91,-0.7 -1.06,0.43 -1.27,0.51 -0.7,-1.21 1.08,-0.84 0.89,-0.7 -0.14,-1.13c-0.03,-0.31 -0.05,-0.54 -0.05,-0.74s0.02,-0.43 0.05,-0.73l0.14,-1.13 -0.89,-0.7 -1.08,-0.84 0.7,-1.21 1.27,0.51 1.04,0.42 0.9,-0.68c0.43,-0.32 0.84,-0.56 1.25,-0.73l1.06,-0.43 0.16,-1.13 0.2,-1.35h1.39l0.19,1.35 0.16,1.13 1.06,0.43c0.43,0.18 0.83,0.41 1.23,0.71l0.91,0.7 1.06,-0.43 1.27,-0.51 0.7,1.21 -1.07,0.85 -0.89,0.7 0.14,1.13zM12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM12,14c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2z"/>
</vector>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+89
View File
@@ -0,0 +1,89 @@
<?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/root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="8dp"
tools:context=".MainActivity"
android:orientation="vertical"
android:backgroundTint="?attr/colorTintBackground">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/app_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textSize="26sp"
android:textColor="?attr/colorPrimary"
android:layout_marginVertical="8dp"
android:fontFamily="@font/mono_bold_italic"
android:layout_gravity="center_horizontal"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<ImageView
android:id="@+id/button_backup_upload"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/cloud_upload"
android:padding="4dp"
android:layout_marginEnd="16dp"
app:layout_constraintTop_toTopOf="@id/app_title"
app:layout_constraintBottom_toBottomOf="@id/app_title"
app:layout_constraintEnd_toEndOf="parent"
android:visibility="gone"/>
<ImageView
android:id="@+id/button_backup_download"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/cloud_download"
android:padding="4dp"
android:layout_marginStart="16dp"
app:layout_constraintTop_toTopOf="@id/app_title"
app:layout_constraintBottom_toBottomOf="@id/app_title"
app:layout_constraintStart_toStartOf="parent"
android:visibility="gone"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraint_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="@menu/nav_items"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:labelVisibilityMode="selected"/>
<!-- android:background="?attr/colorPrimary"-->
<!-- app:itemIconTint="@color/bottom_nav_color"-->
<!-- app:itemTextColor="@color/bottom_nav_color"-->
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_nav"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginVertical="8dp"
android:layout_marginHorizontal="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/guide1"
android:textSize="18sp"/>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
@@ -0,0 +1,34 @@
<?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/quote_constraint_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/quote_scroller"
android:layout_width="0dp"
android:layout_height="0dp"
android:paddingBottom="84dp"
android:clipToPadding="false"
android:layout_marginHorizontal="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/add_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:backgroundTint="?attr/colorOnPrimary"
android:src="@drawable/add"
app:tint="?attr/colorPrimary"/>
<!-- app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlayExtended"-->
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -0,0 +1,438 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.core.widget.NestedScrollView
android:id="@+id/settings_scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical">
<LinearLayout
android:id="@+id/animation_ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingHorizontal="8dp"
android:animateLayoutChanges="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:animateLayoutChanges="true">
<com.denizd.textbasic.VerticalTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text_size"
android:textSize="12sp"
android:fontFamily="@font/mono_light"
android:padding="4dp"/>
<NumberPicker
android:id="@+id/text_size_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="4dp"/>
<com.denizd.textbasic.VerticalTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/opacity"
android:textSize="12sp"
android:fontFamily="@font/mono_light"
android:padding="4dp"/>
<NumberPicker
android:id="@+id/transparency_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="4dp"/>
<com.denizd.textbasic.VerticalTextView
android:id="@+id/outline_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/intensity"
android:textSize="12sp"
android:fontFamily="@font/mono_light"
android:padding="4dp"/>
<NumberPicker
android:id="@+id/outline_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="4dp"/>
</LinearLayout>
<com.google.android.material.button.MaterialButtonToggleGroup
android:id="@+id/typeface_toggle_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_marginBottom="8dp"
app:singleSelection="true"
app:selectionRequired="true">
<com.google.android.material.button.MaterialButton
android:id="@+id/button1_sansserif"
android:layout_width="0dp"
android:layout_weight="3"
android:layout_height="wrap_content"
android:text="@string/sansserif"
android:padding="1dp"
style="?attr/materialButtonOutlinedStyle"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/button2_serif"
android:layout_width="0dp"
android:layout_weight="3"
android:layout_height="wrap_content"
android:text="@string/serif"
android:padding="1dp"
style="?attr/materialButtonOutlinedStyle"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/button3_monospace"
android:layout_width="0dp"
android:layout_weight="3"
android:layout_height="wrap_content"
android:text="@string/monospace"
android:padding="1dp"
style="?attr/materialButtonOutlinedStyle"/>
</com.google.android.material.button.MaterialButtonToggleGroup>
<!-- <com.google.android.material.textfield.TextInputLayout-->
<!-- style="@style/Widget.Material3.TextInputLayout.OutlinedBox.Dense.ExposedDropdownMenu"-->
<!-- android:id="@+id/typeface_menu"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginBottom="16dp">-->
<!-- <AutoCompleteTextView-->
<!-- android:id="@+id/typeface_menu_textview"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:inputType="none"/>-->
<!-- </com.google.android.material.textfield.TextInputLayout>-->
<com.google.android.material.button.MaterialButtonToggleGroup
android:id="@+id/typeface_style_toggle_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_marginBottom="8dp"
app:singleSelection="true"
app:selectionRequired="true">
<com.google.android.material.button.MaterialButton
android:id="@+id/button1_normal"
android:layout_width="0dp"
android:layout_weight="3"
android:layout_height="wrap_content"
android:text="@string/normal"
android:padding="1dp"
style="?attr/materialButtonOutlinedStyle"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/button2_bold"
android:layout_width="0dp"
android:layout_weight="3"
android:layout_height="wrap_content"
android:text="@string/bold"
android:padding="1dp"
style="?attr/materialButtonOutlinedStyle"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/button3_italics"
android:layout_width="0dp"
android:layout_weight="3"
android:layout_height="wrap_content"
android:text="@string/italics"
android:padding="1dp"
style="?attr/materialButtonOutlinedStyle"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/button4_bold_italics"
android:layout_width="0dp"
android:layout_weight="4"
android:layout_height="wrap_content"
android:text="@string/bold_italics"
android:padding="1dp"
style="?attr/materialButtonOutlinedStyle"/>
</com.google.android.material.button.MaterialButtonToggleGroup>
<com.google.android.material.button.MaterialButtonToggleGroup
android:id="@+id/background_toggle_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_marginBottom="8dp"
app:singleSelection="true"
app:selectionRequired="true">
<com.google.android.material.button.MaterialButton
android:id="@+id/button1_background"
android:layout_width="0dp"
android:layout_weight="4"
android:layout_height="wrap_content"
android:text="@string/background"
android:padding="1dp"
style="?attr/materialButtonOutlinedStyle"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/button2_outline"
android:layout_width="0dp"
android:layout_weight="3"
android:layout_height="wrap_content"
android:text="@string/outline"
android:padding="1dp"
style="?attr/materialButtonOutlinedStyle"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/button3_shadow"
android:layout_width="0dp"
android:layout_weight="3"
android:layout_height="wrap_content"
android:text="@string/shadow"
android:padding="1dp"
style="?attr/materialButtonOutlinedStyle"/>
</com.google.android.material.button.MaterialButtonToggleGroup>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/invert"
android:textSize="16sp"
android:fontFamily="@font/mono_regular"
android:layout_marginStart="12dp"
android:layout_marginEnd="36dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<!-- android:textColor="?attr/colorOnPrimary"-->
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/switch_invert"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/random"
android:textSize="16sp"
android:fontFamily="@font/mono_regular"
android:layout_marginStart="12dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="36dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/switch_random"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:id="@+id/text_preview_background_light"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:background="@color/md_theme_light_background">
<LinearLayout
android:id="@+id/text_preview_background_dark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/md_theme_dark_background">
<ImageView
android:id="@+id/text_preview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="4dp"/>
</LinearLayout>
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.denizd.textbasic.VerticalTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/position"
android:textSize="12sp"
android:fontFamily="@font/mono_light"
android:padding="4dp"
android:layout_marginEnd="4dp"
app:layout_constraintEnd_toStartOf="@+id/gravity_buttons_container"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<com.google.android.material.card.MaterialCardView
android:id="@+id/gravity_buttons_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardCornerRadius="12dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:padding="8dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="12dp">
<!-- android:backgroundTint="?attr/colorSecondary"-->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center">
<ImageButton
android:id="@+id/button_top_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/arrow_top_left"
android:background="@android:color/transparent"
android:padding="@dimen/orientation_button_padding"/>
<ImageButton
android:id="@+id/button_top_middle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/arrow_top"
android:background="@android:color/transparent"
android:padding="@dimen/orientation_button_padding"/>
<ImageButton
android:id="@+id/button_top_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/arrow_top_right"
android:background="@android:color/transparent"
android:padding="@dimen/orientation_button_padding"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:visibility="gone">
<ImageButton
android:id="@+id/button_middle_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/arrow_left"
android:background="@android:color/transparent"
android:padding="@dimen/orientation_button_padding"/>
<ImageButton
android:id="@+id/button_middle_middle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/dot"
android:background="@android:color/transparent"
android:padding="@dimen/orientation_button_padding"/>
<ImageButton
android:id="@+id/button_middle_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/arrow_right"
android:background="@android:color/transparent"
android:padding="@dimen/orientation_button_padding"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center">
<ImageButton
android:id="@+id/button_bottom_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/arrow_bottom_left"
android:background="@android:color/transparent"
android:padding="@dimen/orientation_button_padding"/>
<ImageButton
android:id="@+id/button_bottom_middle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/arrow_bottom"
android:background="@android:color/transparent"
android:padding="@dimen/orientation_button_padding"/>
<ImageButton
android:id="@+id/button_bottom_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/arrow_bottom_right"
android:background="@android:color/transparent"
android:padding="@dimen/orientation_button_padding"/>
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>
+44
View File
@@ -0,0 +1,44 @@
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp">
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="16dp">
<!-- android:backgroundTint="?attr/colorSecondary"-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="12dp"
android:layout_marginVertical="8dp"
android:orientation="horizontal">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/quote"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textCursorDrawable="@null"
android:hint="@string/enter_text"/>
<!-- android:theme="@style/ThemeOverlay.AppTheme.TextInputEditText.Outlined"-->
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/delete_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/delete"
android:background="@null"
android:layout_gravity="center_vertical"
android:layout_marginStart="4dp"/>
<!-- android:tint="?attr/colorOnPrimary"-->
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
+15
View File
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/bmp_root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/bitmap_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingHorizontal="4dp"/>
</LinearLayout>
+31
View File
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<LinearLayout
android:id="@+id/background"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="4dp"
android:background="@drawable/layout_bg">
<TextView
android:id="@+id/widget_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="center"
android:clickable="false"
android:focusable="false"
android:typeface="monospace"/>
<!-- android:textColor="@color/white"-->
</LinearLayout>
<!-- android:fontFamily="@font/manrope_medium"-->
</LinearLayout>
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/quotes"
android:icon="@drawable/pen_outlined"
android:title="@string/edit"
android:enabled="true"/>
<item
android:id="@+id/guide"
android:icon="@drawable/book_outlined"
android:title="@string/guide"
android:enabled="true"/>
<item
android:id="@+id/settings"
android:icon="@drawable/settings_outlined"
android:title="@string/settings"
android:enabled="true"/>
</menu>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

+36
View File
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Text Basic</string>
<string name="enter_text">Gib etwas ein...</string>
<string name="example_text">Dies ist ein Beispieltext</string>
<string name="text_size">Textgröße</string>
<string name="opacity">Opazität</string>
<string name="thickness">Dicke</string>
<string name="intensity">Stärke</string>
<string name="invert">Farben umkehren</string>
<string name="random">Zufällige Reihenfolge</string>
<string name="contrast">Kontrast erhöhen</string>
<string name="info_add_text">Füg etwas hinzu!</string>
<string name="snack_backup_download">Daten werden wiederhergestellt...</string>
<string name="snack_backup_upload">Deine Daten werden innerhalb der nächsten Stunde gesichert</string>
<string name="edit">Text bearbeiten</string>
<string name="guide">Anleitung</string>
<string name="settings">Einstellungen</string>
<string name="position">Position</string>
<string name="sansserif">Sans-Serif</string>
<string name="serif">Serif</string>
<string name="monospace">Monospace</string>
<string name="background">Hintergrund</string>
<string name="outline">Umriss</string>
<string name="shadow">Schatten</string>
<string name="normal">Normal</string>
<string name="bold">Fett</string>
<string name="italics">Kursiv</string>
<string name="bold_italics">Fett &amp; kursiv</string>
<string name="guide1"><i>Text Basic</i> ist eine einfache App, um einen beliebigen Text auf deinem Startbildschirm darzustellen! Füge einfach das <i>Text Basic</i>-Widget auf deinem Startbildschirm hinzu, gib Text in die App ein, und der Text wird auf deinem Bildschirm angezeigt.\n\n<b>Wechsle zwischen Texten:</b> In der App kannst du beliebig viele Texte eingeben, indem du den [+]-Knopf drückst und deinen Text in das neu aufgetauchte Feld eingibst. Alle Texte werden automatisch gespeichert, du musst nichts weiteres tun.\nDu kannst zwischen deinen Texten wechseln, indem du auf deinem Startbildschirm auf das Widget klickst. Die Texte werden in der Reihenfolge angezeigt, in der du sie eingegeben hast, du kannst jedoch \"zufällige Reihenfolge\" in den App-Einstellungen aktivieren, um eine willkürliche Reihenfolge zu nutzen.\nHINWEIS: Sollte das Wechseln zwischen Texten nicht klappen, so versuche bitte, das Widget zu vergrößern und wieder zu verkleinern. Danach sollte der Fehler behoben sein.\n\n<b>Verändere den Look:</b> Du kannst verändern, wie der Text aussieht, indem du in die App-Einstellungen schaust dort findest du Optionen für verschiedene Schriftarten und -größen, du kannst die Position bearbeiten sowie den Textstil, und du kannst einen Hintergrund, Umriss, oder Schatten hinzufügen.\nTipp: Sollte dein Text durch dein Hintergrundbild nicht leicht zu erkennen sein, versuche die Farben umzukehren.</string>
</resources>
+38
View File
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="AppTheme" parent="Theme.Material3.Dark.NoActionBar">
<item name="colorPrimary">@color/md_theme_dark_primary</item>
<item name="colorOnPrimary">@color/md_theme_dark_onPrimary</item>
<item name="colorPrimaryContainer">@color/md_theme_dark_primaryContainer</item>
<item name="colorOnPrimaryContainer">@color/md_theme_dark_onPrimaryContainer</item>
<item name="colorSecondary">@color/md_theme_dark_secondary</item>
<item name="colorOnSecondary">@color/md_theme_dark_onSecondary</item>
<item name="colorSecondaryContainer">@color/md_theme_dark_secondaryContainer</item>
<item name="colorOnSecondaryContainer">@color/md_theme_dark_onSecondaryContainer</item>
<item name="colorTertiary">@color/md_theme_dark_tertiary</item>
<item name="colorOnTertiary">@color/md_theme_dark_onTertiary</item>
<item name="colorTertiaryContainer">@color/md_theme_dark_tertiaryContainer</item>
<item name="colorOnTertiaryContainer">@color/md_theme_dark_onTertiaryContainer</item>
<item name="colorError">@color/md_theme_dark_error</item>
<item name="colorErrorContainer">@color/md_theme_dark_errorContainer</item>
<item name="colorOnError">@color/md_theme_dark_onError</item>
<item name="colorOnErrorContainer">@color/md_theme_dark_onErrorContainer</item>
<item name="android:colorBackground">@color/md_theme_dark_background</item>
<item name="colorOnBackground">@color/md_theme_dark_onBackground</item>
<item name="colorSurface">@color/md_theme_dark_surface</item>
<item name="colorOnSurface">@color/md_theme_dark_onSurface</item>
<item name="colorSurfaceVariant">@color/md_theme_dark_surfaceVariant</item>
<item name="colorOnSurfaceVariant">@color/md_theme_dark_onSurfaceVariant</item>
<item name="colorOutline">@color/md_theme_dark_outline</item>
<item name="colorOnSurfaceInverse">@color/md_theme_dark_inverseOnSurface</item>
<item name="colorSurfaceInverse">@color/md_theme_dark_inverseSurface</item>
<item name="colorPrimaryInverse">@color/md_theme_dark_inversePrimary</item>
<item name="colorSecContainer">@color/md_theme_dark_secondaryContainer</item>
<item name="colorTintBackground">@color/color_tint_background_dark</item>
<item name="android:statusBarColor">@color/md_theme_dark_background</item>
<item name="android:navigationBarColor">@color/color_tint_background_dark</item>
</style>
</resources>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- <attr name="colorOnPrimarySoftest" format="color"/>-->
<!-- <attr name="colorOnSecondarySoft" format="color"/>-->
<!-- <attr name="colorTertiary" format="color"/>-->
<attr name="colorTintBackground" format="color"/>
<attr name="colorSecContainer" format="color"/>
</resources>
+72
View File
@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="seed">#91379e</color>
<color name="md_theme_light_primary">#91379E</color>
<color name="md_theme_light_onPrimary">#FFFFFF</color>
<color name="md_theme_light_primaryContainer">#FFD6FD</color>
<color name="md_theme_light_onPrimaryContainer">#36003F</color>
<color name="md_theme_light_secondary">#6B586B</color>
<color name="md_theme_light_onSecondary">#FFFFFF</color>
<color name="md_theme_light_secondaryContainer">#F4DBF1</color>
<color name="md_theme_light_onSecondaryContainer">#251626</color>
<color name="md_theme_light_tertiary">#82524A</color>
<color name="md_theme_light_onTertiary">#FFFFFF</color>
<color name="md_theme_light_tertiaryContainer">#FFDAD4</color>
<color name="md_theme_light_onTertiaryContainer">#33110C</color>
<color name="md_theme_light_error">#BA1A1A</color>
<color name="md_theme_light_errorContainer">#FFDAD6</color>
<color name="md_theme_light_onError">#FFFFFF</color>
<color name="md_theme_light_onErrorContainer">#410002</color>
<color name="md_theme_light_background">#FFFBFF</color>
<color name="md_theme_light_onBackground">#1E1A1D</color>
<color name="md_theme_light_surface">#FFFBFF</color>
<color name="md_theme_light_onSurface">#1E1A1D</color>
<color name="md_theme_light_surfaceVariant">#ECDFE8</color>
<color name="md_theme_light_onSurfaceVariant">#4D444C</color>
<color name="md_theme_light_outline">#7F747C</color>
<color name="md_theme_light_inverseOnSurface">#F7EEF3</color>
<color name="md_theme_light_inverseSurface">#332F32</color>
<color name="md_theme_light_inversePrimary">#FAABFF</color>
<color name="md_theme_light_shadow">#000000</color>
<color name="md_theme_light_surfaceTint">#91379E</color>
<color name="md_theme_light_outlineVariant">#D0C3CC</color>
<color name="md_theme_light_scrim">#000000</color>
<color name="md_theme_dark_primary">#FAABFF</color>
<color name="md_theme_dark_onPrimary">#570065</color>
<color name="md_theme_dark_primaryContainer">#761A84</color>
<color name="md_theme_dark_onPrimaryContainer">#FFD6FD</color>
<color name="md_theme_dark_secondary">#D8BFD5</color>
<color name="md_theme_dark_onSecondary">#3B2B3C</color>
<color name="md_theme_dark_secondaryContainer">#534153</color>
<color name="md_theme_dark_onSecondaryContainer">#F4DBF1</color>
<color name="md_theme_dark_tertiary">#F6B8AD</color>
<color name="md_theme_dark_onTertiary">#4C251F</color>
<color name="md_theme_dark_tertiaryContainer">#673B34</color>
<color name="md_theme_dark_onTertiaryContainer">#FFDAD4</color>
<color name="md_theme_dark_error">#FFB4AB</color>
<color name="md_theme_dark_errorContainer">#93000A</color>
<color name="md_theme_dark_onError">#690005</color>
<color name="md_theme_dark_onErrorContainer">#FFDAD6</color>
<color name="md_theme_dark_background">#1E1A1D</color>
<color name="md_theme_dark_onBackground">#E9E0E4</color>
<color name="md_theme_dark_surface">#1E1A1D</color>
<color name="md_theme_dark_onSurface">#E9E0E4</color>
<color name="md_theme_dark_surfaceVariant">#4D444C</color>
<color name="md_theme_dark_onSurfaceVariant">#D0C3CC</color>
<color name="md_theme_dark_outline">#998D96</color>
<color name="md_theme_dark_inverseOnSurface">#1E1A1D</color>
<color name="md_theme_dark_inverseSurface">#E9E0E4</color>
<color name="md_theme_dark_inversePrimary">#91379E</color>
<color name="md_theme_dark_shadow">#000000</color>
<color name="md_theme_dark_surfaceTint">#FAABFF</color>
<color name="md_theme_dark_outlineVariant">#4D444C</color>
<color name="md_theme_dark_scrim">#000000</color>
<color name="color_tint_background_light">#f3ecf4</color>
<color name="color_tint_background_dark">#30262f</color>
<color name="black">#000000</color>
<color name="white">#ffffff</color>
<color name="widget_dark">#212121</color>
<color name="widget_light">#f0f0f0</color>
</resources>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="orientation_button_padding">12dp</dimen>
</resources>
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#F7ADFC</color>
</resources>
+46
View File
@@ -0,0 +1,46 @@
<resources>
<string name="app_name">Text Basic</string>
<string name="enter_text">Enter something...</string>
<string name="example_text">This is an example text</string>
<string name="text_size">text size</string>
<string name="opacity">opacity</string>
<string name="thickness">thickness</string>
<string name="intensity">intensity</string>
<string name="invert">Invert colours</string>
<string name="random">Randomise order</string>
<string name="contrast">Increase the contrast</string>
<string name="info_add_text">add some text!</string>
<string name="snack_backup_download">Restoring your data...</string>
<string name="snack_backup_upload">Your data will be backed up within the next hour</string>
<string name="edit">Edit Text</string>
<string name="guide">Guide</string>
<string name="settings">Settings</string>
<string name="position">position</string>
<string name="sansserif">Sans-Serif</string>
<string name="serif">Serif</string>
<string name="monospace">Monospace</string>
<string name="background">Background</string>
<string name="outline">Outline</string>
<string name="shadow">Shadow</string>
<string name="normal">Normal</string>
<string name="bold">Bold</string>
<string name="italics">Italics</string>
<string name="bold_italics">Bold &amp; Italics</string>
<string name="guide1"><i>Text Basic</i> is a simple app for displaying a text on your home screen! Just add the <i>Text Basic</i> widget to your home screen, enter text in the app, and it will show on your home screen.
\n\n<b>Cycle through texts:</b> In the app, you can enter as many texts as you like by clicking the [+] button and entering your text into the newly appeared field. All texts are saved automatically, you have to take no further action.\nYou can cycle through your texts by clicking on the widget on your home screen. They will be shown in the order you added them in, but you can turn on "random order" in the app\'s settings to randomise the order.
\nNOTE: if clicking on the widget does not cycle between texts, please try changing the size of the widget and then change it back. This should solve the issue.
\n\n<b>Customise the look:</b> You can change how your text will look by heading into the app\'s settings there, you can edit the text appearance by changing the size, font, position, apply formatting options, and even add a background, an outline, or a shadow.
\nTip: if the text is hard to read on your wallpaper, try inverting the colours.</string>
<string-array name="typefaces">
<item>Sans-Serif</item>
<item>Serif</item>
<item>Monospace</item>
</string-array>
</resources>
+40
View File
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="AppTheme" parent="Theme.Material3.Light.NoActionBar">
<item name="colorPrimary">@color/md_theme_light_primary</item>
<item name="colorOnPrimary">@color/md_theme_light_onPrimary</item>
<item name="colorPrimaryContainer">@color/md_theme_light_primaryContainer</item>
<item name="colorOnPrimaryContainer">@color/md_theme_light_onPrimaryContainer</item>
<item name="colorSecondary">@color/md_theme_light_secondary</item>
<item name="colorOnSecondary">@color/md_theme_light_onSecondary</item>
<item name="colorSecondaryContainer">@color/md_theme_light_secondaryContainer</item>
<item name="colorOnSecondaryContainer">@color/md_theme_light_onSecondaryContainer</item>
<item name="colorTertiary">@color/md_theme_light_tertiary</item>
<item name="colorOnTertiary">@color/md_theme_light_onTertiary</item>
<item name="colorTertiaryContainer">@color/md_theme_light_tertiaryContainer</item>
<item name="colorOnTertiaryContainer">@color/md_theme_light_onTertiaryContainer</item>
<item name="colorError">@color/md_theme_light_error</item>
<item name="colorErrorContainer">@color/md_theme_light_errorContainer</item>
<item name="colorOnError">@color/md_theme_light_onError</item>
<item name="colorOnErrorContainer">@color/md_theme_light_onErrorContainer</item>
<item name="android:colorBackground">@color/md_theme_light_background</item>
<item name="colorOnBackground">@color/md_theme_light_onBackground</item>
<item name="colorSurface">@color/md_theme_light_surface</item>
<item name="colorOnSurface">@color/md_theme_light_onSurface</item>
<item name="colorSurfaceVariant">@color/md_theme_light_surfaceVariant</item>
<item name="colorOnSurfaceVariant">@color/md_theme_light_onSurfaceVariant</item>
<item name="colorOutline">@color/md_theme_light_outline</item>
<item name="colorOnSurfaceInverse">@color/md_theme_light_inverseOnSurface</item>
<item name="colorSurfaceInverse">@color/md_theme_light_inverseSurface</item>
<item name="colorPrimaryInverse">@color/md_theme_light_inversePrimary</item>
<item name="colorSecContainer">@color/md_theme_light_secondaryContainer</item>
<item name="colorTintBackground">@color/color_tint_background_light</item>
<item name="android:statusBarColor">@color/md_theme_light_background</item>
<item name="android:navigationBarColor">@color/color_tint_background_light</item>
<item name="android:windowLightStatusBar">true</item>
<item name="android:windowLightNavigationBar" tools:targetApi="p">true</item>
</style>
</resources>
+9
View File
@@ -0,0 +1,9 @@
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="1dp"
android:minHeight="1dp"
android:updatePeriodMillis="86400000"
android:previewImage="@drawable/hellothere"
android:initialLayout="@layout/widget_bitmap"
android:resizeMode="horizontal|vertical"
android:widgetCategory="home_screen">
</appwidget-provider>
@@ -0,0 +1,17 @@
package com.denizd.textbasic
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}