This commit is contained in:
lunaticbum 2025-08-17 16:17:52 +09:00
parent c2e4e01036
commit 5c7325843c
24 changed files with 3280 additions and 97 deletions

View File

@ -119,7 +119,7 @@ dependencies {
// implementation 'com.vladsch.flexmark:flexmark-all:0.64.8' // implementation 'com.vladsch.flexmark:flexmark-all:0.64.8'
// implementation("org.opencv:opencv-android:4.11.0") // implementation("org.opencv:opencv-android:4.11.0")
// build.gradle에 추가 // build.gradle에 추가
implementation ("com.github.aeonSolutions:FloatingActionButtonMenuDrag:1.1") // implementation ("com.github.aeonSolutions:FloatingActionButtonMenuDrag:1.1")

View File

@ -524,6 +524,10 @@ open class LauncherActivity : CommonActivity() {
var isKeyboardVisible = false var isKeyboardVisible = false
fun setAddr(str : String) {
binding.currentAddress.text = str
}
@SuppressLint("NewApi", "MissingPermission") @SuppressLint("NewApi", "MissingPermission")
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
installSplashScreen() installSplashScreen()
@ -542,11 +546,6 @@ open class LauncherActivity : CommonActivity() {
HeadsetActionButtonReceiver.register(this) HeadsetActionButtonReceiver.register(this)
binding.tabs.setOnCheckedChangeListener { g, id ->
showContents(id)
}
/* handle navigation back events */ /* handle navigation back events */
handleBackPress() handleBackPress()
updateLocationService() updateLocationService()
@ -563,6 +562,19 @@ open class LauncherActivity : CommonActivity() {
if (intent?.action == Intent.ACTION_WEB_SEARCH) { if (intent?.action == Intent.ACTION_WEB_SEARCH) {
openWithIntent(intent) openWithIntent(intent)
} }
binding.share.setOnClickListener {
if (binding.currentAddress.text.length > 5) {
val sendIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
(binding.currentAddress.tag as? String)?.let{putExtra(Intent.EXTRA_TITLE, it)}
putExtra(Intent.EXTRA_TEXT, binding.currentAddress.text)
type = "text/plain"
}
val shareIntent = Intent.createChooser(sendIntent, "링크 공유하기")
startActivity(shareIntent)
}
}
} }
fun showContents(id : Int) { fun showContents(id : Int) {
@ -609,7 +621,9 @@ open class LauncherActivity : CommonActivity() {
} }
else -> {} else -> {}
} }
binding.floatingActionMenu.close(false)
} }
private fun initGeckoRuntime() { private fun initGeckoRuntime() {
if (sRuntime == null) { if (sRuntime == null) {
try { try {

View File

@ -27,6 +27,7 @@ import android.view.View
import android.widget.CheckBox import android.widget.CheckBox
import android.widget.EditText import android.widget.EditText
import android.widget.ProgressBar import android.widget.ProgressBar
import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.core.net.toUri import androidx.core.net.toUri
@ -73,7 +74,7 @@ class GeckoWeb : BWebview {
var decoViews = arrayListOf<View>() var decoViews = arrayListOf<View>()
override fun setVisibility(visibility: Int) { override fun setVisibility(visibility: Int) {
super.setVisibility(visibility) super.setVisibility(visibility)
decoViews.forEach { it.visibility = visibility } decoViews.filter { it != null && it.id > -1 }.forEach { it.visibility = visibility }
} }
interface OnSave { interface OnSave {
fun saved() fun saved()
@ -438,12 +439,14 @@ class GeckoWeb : BWebview {
} }
fun getFilterF() = String(java.util.Base64.getMimeDecoder().decode("aHR0cHM6Ly9pamF2dG9ycmVudC5jb20=".toByteArray())) fun getFilterF() = String(java.util.Base64.getMimeDecoder().decode("aHR0cHM6Ly9pamF2dG9ycmVudC5jb20=".toByteArray()))
var currentTitle = ""
val contentDelegate = object : GeckoSession.ContentDelegate { val contentDelegate = object : GeckoSession.ContentDelegate {
override fun onTitleChange( override fun onTitleChange(
session: GeckoSession, session: GeckoSession,
title: String? title: String?
) { ) {
Blog.LOGE("onTitleChange $title") Blog.LOGE("onTitleChange $title")
currentTitle = title ?: ""
super.onTitleChange(session, title) super.onTitleChange(session, title)
} }
@ -620,12 +623,20 @@ class GeckoWeb : BWebview {
} }
decoViews?.forEach { decoViews.filter { it != null && it.id > -1 }.forEach {
if (it != null && it.id > -1) {
if (it.id == R.id.back) { if (it.id == R.id.back) {
it.setOnClickListener { session.goBack() } it.setOnClickListener { session.goBack() }
} else if (it.id == R.id.current_address) {
(it as? TextView)?.let {
it.tag = currentTitle
it.text = url
} }
} }
} }
}
}
override fun onCanGoBack(session: GeckoSession, canGoBack: Boolean) { override fun onCanGoBack(session: GeckoSession, canGoBack: Boolean) {
super.onCanGoBack(session, canGoBack) super.onCanGoBack(session, canGoBack)
@ -888,12 +899,16 @@ class GeckoWeb : BWebview {
} }
} else if (url.startsWith("http") == false) { } else if (url.startsWith("http") == false) {
nUrl = lastDomain nUrl = lastDomain
} else { } else if(param != null && param?.length ?: 0 > 1) {
nUrl = url.plus(param) nUrl = url.plus(param)
} else {
nUrl = url
} }
if (!privateMode && this.isVisible == false) { if (!privateMode && this.isVisible == false) {
this.visibility = View.VISIBLE this.visibility = View.VISIBLE
} }
Blog.LOGE("nUrl >>>> ${nUrl}") Blog.LOGE("nUrl >>>> ${nUrl}")

View File

@ -34,7 +34,9 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.CheckBox import android.widget.CheckBox
import android.widget.EditText import android.widget.EditText
import android.widget.ImageButton
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.annotation.NonNull import androidx.annotation.NonNull
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
@ -44,7 +46,9 @@ import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import bums.lunatic.launcher.LauncherActivity
import bums.lunatic.launcher.LauncherActivity.Companion.lActivity import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
import bums.lunatic.launcher.LunaticLauncher
import bums.lunatic.launcher.R import bums.lunatic.launcher.R
import bums.lunatic.launcher.common.letTrue import bums.lunatic.launcher.common.letTrue
import bums.lunatic.launcher.databinding.LauncherHomeBinding import bums.lunatic.launcher.databinding.LauncherHomeBinding
@ -503,16 +507,11 @@ internal class RssHome : Fragment() {
vote() vote()
} }
} }
binding.share.setOnClickListener {
binding.geckoWeb.saveMd()
}
Blog.LOGE("useHiddenMenu >>> $openQuery") Blog.LOGE("useHiddenMenu >>> $openQuery")
if (openQuery.length > 0) { if (openQuery.length > 0) {
binding.geckoWeb.loadUrl("https://www.google.com/search?q=${openQuery}") binding.geckoWeb.loadUrl("https://www.google.com/search?q=${openQuery}")
openQuery = "" openQuery = ""
} else {
binding.privateBtn.visibility = View.GONE
binding.search.visibility = View.GONE
} }
binding.geckoWeb?.mOnSave = object : GeckoWeb.OnSave{ binding.geckoWeb?.mOnSave = object : GeckoWeb.OnSave{
override fun saved() { override fun saved() {
@ -544,6 +543,7 @@ internal class RssHome : Fragment() {
if (it.vote) { if (it.vote) {
it.vote = false it.vote = false
} }
it.hide = true
} }
} }
} }
@ -607,11 +607,21 @@ internal class RssHome : Fragment() {
} }
} }
val nullCursor = PointerIcon.getSystemIcon(requireContext(), PointerIcon.TYPE_NULL) val nullCursor = PointerIcon.getSystemIcon(requireContext(), PointerIcon.TYPE_NULL)
binding.search.setOnClickListener { searchKeyword() }
binding.search.setOnLongClickListener{
ask()
true
}
binding.root.setPointerIcon(nullCursor) binding.root.setPointerIcon(nullCursor)
binding.geckoWeb.decoViews.add(binding.hide) binding.geckoWeb.decoViews.add(binding.hide)
binding.geckoWeb.decoViews.add(binding.vote) binding.geckoWeb.decoViews.add(binding.vote)
binding.geckoWeb.decoViews.add(binding.progressBar) binding.geckoWeb.decoViews.add(binding.progressBar)
binding.geckoWeb.decoViews.add(binding.back) (activity as? LauncherActivity)?.let { activity ->
binding.geckoWeb.decoViews.add(activity.findViewById<TextView>(R.id.current_address))
binding.geckoWeb.decoViews.add(activity.findViewById<ImageButton>(R.id.back))
}
return binding.root return binding.root
} }

View File

@ -17,8 +17,10 @@ import android.widget.Button
import android.widget.CheckBox import android.widget.CheckBox
import android.widget.EditText import android.widget.EditText
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.RadioButton
import android.widget.RadioGroup import android.widget.RadioGroup
import android.widget.Toast import android.widget.Toast
import androidx.core.view.forEach
import bums.lunatic.launcher.R import bums.lunatic.launcher.R
import bums.lunatic.launcher.model.RssDataType import bums.lunatic.launcher.model.RssDataType
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
@ -62,6 +64,7 @@ class SearchBottomSheet : BottomSheetDialogFragment() {
for (category in categories) { for (category in categories) {
val btn = Button(requireContext()).apply { val btn = Button(requireContext()).apply {
text = category.name text = category.name
tag = category
isAllCaps = false isAllCaps = false
setBackgroundResource(android.R.drawable.btn_default) setBackgroundResource(android.R.drawable.btn_default)
setTextColor(Color.WHITE) setTextColor(Color.WHITE)
@ -72,6 +75,17 @@ class SearchBottomSheet : BottomSheetDialogFragment() {
this.isSelected = !this.isSelected this.isSelected = !this.isSelected
triggerSearchWithDebounce(inputKeyword.text.toString()) triggerSearchWithDebounce(inputKeyword.text.toString())
} }
setOnLongClickListener {
categoryContainer.forEach {
categoryStates[(it.tag as RssDataType).name] = false
it.isSelected = false
}
categoryStates[(it.tag as RssDataType).name] = true
it.isSelected = true
triggerSearchWithDebounce(inputKeyword.text.toString())
true
}
} }
categoryContainer.addView(btn) categoryContainer.addView(btn)
} }

View File

@ -22,6 +22,7 @@ import android.widget.RadioButton
import android.widget.RadioGroup import android.widget.RadioGroup
import android.widget.Toast import android.widget.Toast
import androidx.core.view.children import androidx.core.view.children
import androidx.core.view.forEach
import bums.lunatic.launcher.R import bums.lunatic.launcher.R
import bums.lunatic.launcher.model.RssDataType import bums.lunatic.launcher.model.RssDataType
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
@ -81,6 +82,12 @@ class WebBottomSheet : BottomSheetDialogFragment() {
setOnClickListener { setOnClickListener {
triggerSearchWithDebounce(inputKeyword.text.toString()) triggerSearchWithDebounce(inputKeyword.text.toString())
} }
// setOnLongClickListener {
// categoryContainer.forEach { (it as? RadioButton)?.let { it.isChecked = false} }
// (it as? RadioButton)?.let { it.isChecked = }
// triggerSearchWithDebounce(inputKeyword.text.toString())
// true
// }
} }
categoryContainer.addView(btn) categoryContainer.addView(btn)
} }

View File

@ -249,6 +249,7 @@ class RssData : RealmObject, RssDataInterface {
var chosung : String? = null var chosung : String? = null
var vote : Boolean = false var vote : Boolean = false
var read : Int = 0 var read : Int = 0
var hide : Boolean = false
@Ignore @Ignore
var mRssDataType : RssDataType? = null var mRssDataType : RssDataType? = null

View File

@ -0,0 +1,21 @@
package bums.lunatic.launcher.utils
import android.content.Context
import android.os.Build
object CommonUtils {
fun dpToPx(context: Context, dp: Float): Int {
val scale: Float = context.getResources().getDisplayMetrics().density
return Math.round(dp * scale)
}
fun hasJellyBean(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
}
fun hasLollipop(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,400 @@
package bums.lunatic.launcher.view
import android.annotation.SuppressLint
import android.annotation.TargetApi
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Canvas
import android.graphics.ColorFilter
import android.graphics.Outline
import android.graphics.Paint
import android.graphics.PorterDuff
import android.graphics.PorterDuffXfermode
import android.graphics.RectF
import android.graphics.Xfermode
import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable
import android.graphics.drawable.RippleDrawable
import android.graphics.drawable.ShapeDrawable
import android.graphics.drawable.StateListDrawable
import android.graphics.drawable.shapes.RoundRectShape
import android.os.Build
import android.util.AttributeSet
import android.view.GestureDetector
import android.view.GestureDetector.SimpleOnGestureListener
import android.view.MotionEvent
import android.view.View
import android.view.ViewOutlineProvider
import android.view.animation.Animation
import android.widget.TextView
import bums.lunatic.launcher.utils.CommonUtils
import kotlin.math.abs
@SuppressLint("AppCompatCustomView")
class Label : TextView {
private var mShadowRadius = 0
private var mShadowXOffset = 0
private var mShadowYOffset = 0
private var mShadowColor = 0
private var mBackgroundDrawable: Drawable? = null
private var mShowShadow = true
private var mRawWidth = 0
private var mRawHeight = 0
private var mColorNormal = 0
private var mColorPressed = 0
private var mColorRipple = 0
private var mCornerRadius = 0
private var mFab: FloatingActionButton? = null
private var mShowAnimation: Animation? = null
private var mHideAnimation: Animation? = null
private var mUsingStyle = false
var isHandleVisibilityChanges: Boolean = true
constructor(context: Context?) : super(context)
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
)
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
setMeasuredDimension(calculateMeasuredWidth(), calculateMeasuredHeight())
}
private fun calculateMeasuredWidth(): Int {
if (mRawWidth == 0) {
mRawWidth = getMeasuredWidth()
}
return getMeasuredWidth() + calculateShadowWidth()
}
private fun calculateMeasuredHeight(): Int {
if (mRawHeight == 0) {
mRawHeight = getMeasuredHeight()
}
return getMeasuredHeight() + calculateShadowHeight()
}
fun calculateShadowWidth(): Int {
return (if (mShowShadow) (mShadowRadius + abs(mShadowXOffset.toDouble())) else 0).toInt()
}
fun calculateShadowHeight(): Int {
return (if (mShowShadow) (mShadowRadius + abs(mShadowYOffset.toDouble())) else 0).toInt()
}
fun updateBackground() {
val layerDrawable: LayerDrawable?
if (mShowShadow) {
layerDrawable = LayerDrawable(
arrayOf<Drawable>(
this.Shadow(),
createFillDrawable()
)
)
val leftInset: Int = (mShadowRadius + abs(mShadowXOffset.toDouble())).toInt()
val topInset: Int = (mShadowRadius + abs(mShadowYOffset.toDouble())).toInt()
val rightInset: Int = ((mShadowRadius + abs(mShadowXOffset.toDouble()))).toInt()
val bottomInset: Int = ((mShadowRadius + abs(mShadowYOffset.toDouble()))).toInt()
layerDrawable.setLayerInset(
1,
leftInset,
topInset,
rightInset,
bottomInset
)
} else {
layerDrawable = LayerDrawable(
arrayOf<Drawable>(
createFillDrawable()
)
)
}
setBackgroundCompat(layerDrawable)
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private fun createFillDrawable(): Drawable {
val drawable = StateListDrawable()
drawable.addState(intArrayOf(android.R.attr.state_pressed), createRectDrawable(mColorPressed))
drawable.addState(intArrayOf(), createRectDrawable(mColorNormal))
if (CommonUtils.hasLollipop()) {
val ripple = RippleDrawable(
ColorStateList(
arrayOf<IntArray?>(intArrayOf()),
intArrayOf(mColorRipple)
), drawable, null
)
setOutlineProvider(object : ViewOutlineProvider() {
override fun getOutline(view: View, outline: Outline) {
outline.setOval(0, 0, view.getWidth(), view.getHeight())
}
})
setClipToOutline(true)
mBackgroundDrawable = ripple
return ripple
}
mBackgroundDrawable = drawable
return drawable
}
private fun createRectDrawable(color: Int): Drawable {
val shape = RoundRectShape(
floatArrayOf(
mCornerRadius.toFloat(),
mCornerRadius.toFloat(),
mCornerRadius.toFloat(),
mCornerRadius.toFloat(),
mCornerRadius.toFloat(),
mCornerRadius.toFloat(),
mCornerRadius.toFloat(),
mCornerRadius.toFloat()
),
null,
null
)
val shapeDrawable = ShapeDrawable(shape)
shapeDrawable.getPaint().setColor(color)
return shapeDrawable
}
private fun setShadow(fab: FloatingActionButton) {
mShadowColor = fab.shadowColor
mShadowRadius = fab.shadowRadius
mShadowXOffset = fab.shadowXOffset
mShadowYOffset = fab.shadowYOffset
mShowShadow = fab.hasShadow()
}
@Suppress("deprecation")
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private fun setBackgroundCompat(drawable: Drawable?) {
if (CommonUtils.hasJellyBean()) {
setBackground(drawable)
} else {
setBackgroundDrawable(drawable)
}
}
private fun playShowAnimation() {
if (mShowAnimation != null) {
mHideAnimation!!.cancel()
startAnimation(mShowAnimation)
}
}
private fun playHideAnimation() {
if (mHideAnimation != null) {
mShowAnimation!!.cancel()
startAnimation(mHideAnimation)
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
fun onActionDown() {
if (mUsingStyle) {
mBackgroundDrawable = getBackground()
}
if (mBackgroundDrawable is StateListDrawable) {
val drawable = mBackgroundDrawable as StateListDrawable
drawable.setState(intArrayOf(android.R.attr.state_pressed))
} else if (CommonUtils.hasLollipop() && mBackgroundDrawable is RippleDrawable) {
val ripple = mBackgroundDrawable as RippleDrawable
ripple.setState(intArrayOf(android.R.attr.state_enabled, android.R.attr.state_pressed))
ripple.setHotspot(
(getMeasuredWidth() / 2).toFloat(),
(getMeasuredHeight() / 2).toFloat()
)
ripple.setVisible(true, true)
}
// setPressed(true);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
fun onActionUp() {
if (mUsingStyle) {
mBackgroundDrawable = getBackground()
}
if (mBackgroundDrawable is StateListDrawable) {
val drawable = mBackgroundDrawable as StateListDrawable
drawable.setState(intArrayOf())
} else if (CommonUtils.hasLollipop() && mBackgroundDrawable is RippleDrawable) {
val ripple = mBackgroundDrawable as RippleDrawable
ripple.setState(intArrayOf())
ripple.setHotspot(
(getMeasuredWidth() / 2).toFloat(),
(getMeasuredHeight() / 2).toFloat()
)
ripple.setVisible(true, true)
}
// setPressed(false);
}
fun setFab(fab: FloatingActionButton) {
mFab = fab
setShadow(fab)
}
fun setShowShadow(show: Boolean) {
mShowShadow = show
}
fun setCornerRadius(cornerRadius: Int) {
mCornerRadius = cornerRadius
}
fun setColors(colorNormal: Int, colorPressed: Int, colorRipple: Int) {
mColorNormal = colorNormal
mColorPressed = colorPressed
mColorRipple = colorRipple
}
fun show(animate: Boolean) {
if (animate) {
playShowAnimation()
}
setVisibility(VISIBLE)
}
fun hide(animate: Boolean) {
if (animate) {
playHideAnimation()
}
setVisibility(INVISIBLE)
}
fun setShowAnimation(showAnimation: Animation?) {
mShowAnimation = showAnimation
}
fun setHideAnimation(hideAnimation: Animation?) {
mHideAnimation = hideAnimation
}
fun setUsingStyle(usingStyle: Boolean) {
mUsingStyle = usingStyle
}
override fun onTouchEvent(event: MotionEvent): Boolean {
if (mFab == null || mFab!!.getOnClickListener() == null || !mFab!!.isEnabled()) {
return super.onTouchEvent(event)
}
val action = event.getAction()
when (action) {
MotionEvent.ACTION_UP -> {
onActionUp()
mFab!!.onActionUp()
}
MotionEvent.ACTION_CANCEL -> {
onActionUp()
mFab!!.onActionUp()
}
}
mGestureDetector.onTouchEvent(event)
return super.onTouchEvent(event)
}
var mGestureDetector: GestureDetector =
GestureDetector(getContext(), object : SimpleOnGestureListener() {
override fun onDown(e: MotionEvent): Boolean {
onActionDown()
if (mFab != null) {
mFab!!.onActionDown()
}
return super.onDown(e)
}
override fun onSingleTapUp(e: MotionEvent): Boolean {
onActionUp()
if (mFab != null) {
mFab!!.onActionUp()
}
return super.onSingleTapUp(e)
}
})
private inner class Shadow : Drawable {
private val mPaint = Paint(Paint.ANTI_ALIAS_FLAG)
private val mErase = Paint(Paint.ANTI_ALIAS_FLAG)
constructor() : super()
init {
this.init()
}
fun init() {
setLayerType(LAYER_TYPE_SOFTWARE, null)
mPaint.setStyle(Paint.Style.FILL)
mPaint.setColor(mColorNormal)
mErase.setXfermode(PORTER_DUFF_CLEAR)
if (!isInEditMode()) {
mPaint.setShadowLayer(
mShadowRadius.toFloat(),
mShadowXOffset.toFloat(),
mShadowYOffset.toFloat(),
mShadowColor
)
}
}
override fun draw(canvas: Canvas) {
val shadowRect = RectF(
(mShadowRadius + abs(mShadowXOffset.toDouble())).toFloat(),
(mShadowRadius + abs(mShadowYOffset.toDouble())).toFloat(),
mRawWidth.toFloat(),
mRawHeight.toFloat()
)
canvas.drawRoundRect(
shadowRect,
mCornerRadius.toFloat(),
mCornerRadius.toFloat(),
mPaint
)
canvas.drawRoundRect(
shadowRect,
mCornerRadius.toFloat(),
mCornerRadius.toFloat(),
mErase
)
}
override fun setAlpha(alpha: Int) {
}
override fun setColorFilter(colorFilter: ColorFilter?) {
}
override fun getOpacity(): Int {
return 0
}
}
companion object {
private val PORTER_DUFF_CLEAR: Xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
}
}

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/accelerate_quint"
android:fromXScale="1.0"
android:toXScale="0.0"
android:fromYScale="1.0"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="200" />

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/overshoot"
android:fromXScale="0.0"
android:toXScale="1.0"
android:fromYScale="0.0"
android:toYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="200" />

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/overshoot">
<alpha
android:fromAlpha="0"
android:toAlpha="1"
android:duration="300" />
<translate
android:fromXDelta="-15%p"
android:toXDelta="0"
android:duration="200" />
</set>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/overshoot">
<alpha
android:fromAlpha="0"
android:toAlpha="1"
android:duration="300" />
<translate
android:fromXDelta="15%p"
android:toXDelta="0"
android:duration="200" />
</set>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/accelerate_quint">
<alpha
android:fromAlpha="1"
android:toAlpha="0"
android:duration="150" />
<translate
android:fromXDelta="0"
android:toXDelta="-30%p"
android:duration="200" />
</set>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/accelerate_quint">
<alpha
android:fromAlpha="1"
android:toAlpha="0"
android:duration="150" />
<translate
android:fromXDelta="0"
android:toXDelta="30%p"
android:duration="200" />
</set>

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

View File

@ -1,7 +1,7 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:height="24dp" android:width="24dp" android:height="24dp"
android:viewportWidth="24" android:viewportHeight="24" android:viewportWidth="24" android:viewportHeight="24"
android:tint="?attr/colorControlNormal"> android:tint="@color/Color_White">
<path <path
android:fillColor="?android:attr/textColorPrimary" android:fillColor="?android:attr/textColorPrimary"
android:pathData="M11.35,16.75H12.7V12.7H16.75V11.35H12.7V7.25H11.35V11.35H7.25V12.7H11.35ZM12,21.5Q10.025,21.5 8.3,20.75Q6.575,20 5.287,18.725Q4,17.45 3.25,15.712Q2.5,13.975 2.5,12Q2.5,10.025 3.25,8.287Q4,6.55 5.287,5.262Q6.575,3.975 8.3,3.237Q10.025,2.5 12,2.5Q13.975,2.5 15.713,3.237Q17.45,3.975 18.738,5.262Q20.025,6.55 20.763,8.287Q21.5,10.025 21.5,12Q21.5,13.975 20.763,15.7Q20.025,17.425 18.738,18.712Q17.45,20 15.713,20.75Q13.975,21.5 12,21.5ZM12,20.15Q15.425,20.15 17.788,17.787Q20.15,15.425 20.15,12Q20.15,8.575 17.788,6.212Q15.425,3.85 12,3.85Q8.575,3.85 6.213,6.212Q3.85,8.575 3.85,12Q3.85,15.425 6.213,17.787Q8.575,20.15 12,20.15ZM12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Z"/> android:pathData="M11.35,16.75H12.7V12.7H16.75V11.35H12.7V7.25H11.35V11.35H7.25V12.7H11.35ZM12,21.5Q10.025,21.5 8.3,20.75Q6.575,20 5.287,18.725Q4,17.45 3.25,15.712Q2.5,13.975 2.5,12Q2.5,10.025 3.25,8.287Q4,6.55 5.287,5.262Q6.575,3.975 8.3,3.237Q10.025,2.5 12,2.5Q13.975,2.5 15.713,3.237Q17.45,3.975 18.738,5.262Q20.025,6.55 20.763,8.287Q21.5,10.025 21.5,12Q21.5,13.975 20.763,15.7Q20.025,17.425 18.738,18.712Q17.45,20 15.713,20.75Q13.975,21.5 12,21.5ZM12,20.15Q15.425,20.15 17.788,17.787Q20.15,15.425 20.15,12Q20.15,8.575 17.788,6.212Q15.425,3.85 12,3.85Q8.575,3.85 6.213,6.212Q3.85,8.575 3.85,12Q3.85,15.425 6.213,17.787Q8.575,20.15 12,20.15ZM12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Z"/>

View File

@ -19,44 +19,64 @@
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@id/tabs_sc"/> app:layout_constraintBottom_toTopOf="@id/current_address"/>
<HorizontalScrollView <ImageButton
android:id="@+id/tabs_sc" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/fragment_container"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
android:id="@+id/back"
android:scaleType="fitCenter"
android:adjustViewBounds="true"
android:visibility="visible"
android:background="@null"
android:src="@drawable/back_vector"
android:tint="@color/white"
android:foregroundTint="@color/white"
android:layout_width="40dp"
tools:ignore="ContentDescription"
android:layout_height="40dp" />
<TextView
android:text="asdasdsadasd"
android:id="@+id/current_address"
app:layout_constraintTop_toTopOf="@id/back"
app:layout_constraintRight_toLeftOf="@id/share"
app:layout_constraintLeft_toRightOf="@id/back"
android:textColor="@color/white"
android:gravity="center"
android:textSize="@dimen/_12sp"
android:ellipsize="middle"
app:layout_constraintRight_toRightOf="parent"
android:layout_width="0dp"
android:layout_height="40dp"/>
<ImageButton
app:layout_constraintTop_toTopOf="@id/back"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
android:orientation="horizontal" android:layout_marginRight="60dp"
android:layout_width="match_parent" android:id="@+id/share"
android:layout_marginBottom="@dimen/_14sp" android:scaleType="fitCenter"
android:layout_height="wrap_content"> android:adjustViewBounds="true"
<RadioGroup android:visibility="visible"
android:id="@+id/tabs" android:background="@null"
android:orientation="horizontal" android:tint="@color/white"
app:layout_constraintLeft_toLeftOf="parent" android:foregroundTint="@color/white"
app:layout_constraintRight_toRightOf="parent" android:src="@drawable/ic_share"
app:layout_constraintBottom_toBottomOf="parent" android:layout_width="40dp"
app:singleSelection="true" tools:ignore="ContentDescription"
android:layout_width="wrap_content" android:layout_height="40dp" />
android:layout_height="35dp"> <bums.lunatic.launcher.view.FloatingActionMenu
</RadioGroup>
</HorizontalScrollView>
<aeonlabs.solutions.common.layout.fab.FloatingActionMenu
android:id="@+id/floating_action_menu" android:id="@+id/floating_action_menu"
android:layout_margin="5dp" android:layout_margin="5dp"
app:menu_colorNormal="#80FF0000" app:menu_colorNormal="#80FF0000"
app:menu_fab_size="mini" app:menu_fab_size="mini"
app:menu_icon="@drawable/ic_add"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_width="match_parent" android:layout_width="match_parent"
> >
<aeonlabs.solutions.common.layout.fab.FloatingActionButton <bums.lunatic.launcher.view.FloatingActionButton
app:fab_label="feeds" app:fab_label="feeds"
android:id="@+id/feeds" android:id="@+id/feeds"
app:fab_showShadow="true" app:fab_showShadow="true"
@ -64,7 +84,7 @@
android:onClick="floatClick" android:onClick="floatClick"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="20dp"/> android:layout_height="20dp"/>
<aeonlabs.solutions.common.layout.fab.FloatingActionButton <bums.lunatic.launcher.view.FloatingActionButton
app:fab_label="booktoki" app:fab_label="booktoki"
android:id="@+id/books" android:id="@+id/books"
app:fab_showShadow="true" app:fab_showShadow="true"
@ -72,7 +92,7 @@
android:onClick="floatClick" android:onClick="floatClick"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="20dp"/> android:layout_height="20dp"/>
<aeonlabs.solutions.common.layout.fab.FloatingActionButton <bums.lunatic.launcher.view.FloatingActionButton
app:fab_label="newtoki" app:fab_label="newtoki"
android:id="@+id/webtoons" android:id="@+id/webtoons"
app:fab_showShadow="true" app:fab_showShadow="true"
@ -80,7 +100,7 @@
android:onClick="floatClick" android:onClick="floatClick"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="20dp"/> android:layout_height="20dp"/>
<aeonlabs.solutions.common.layout.fab.FloatingActionButton <bums.lunatic.launcher.view.FloatingActionButton
app:fab_label="manatoki" app:fab_label="manatoki"
android:id="@+id/comics" android:id="@+id/comics"
app:fab_showShadow="true" app:fab_showShadow="true"
@ -88,7 +108,7 @@
android:onClick="floatClick" android:onClick="floatClick"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="20dp"/> android:layout_height="20dp"/>
<aeonlabs.solutions.common.layout.fab.FloatingActionButton <bums.lunatic.launcher.view.FloatingActionButton
app:fab_label="perplexity" app:fab_label="perplexity"
android:id="@+id/perplexity" android:id="@+id/perplexity"
app:fab_showShadow="true" app:fab_showShadow="true"
@ -96,7 +116,7 @@
android:onClick="floatClick" android:onClick="floatClick"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="20dp"/> android:layout_height="20dp"/>
<aeonlabs.solutions.common.layout.fab.FloatingActionButton <bums.lunatic.launcher.view.FloatingActionButton
app:fab_label="zota" app:fab_label="zota"
android:id="@+id/zota" android:id="@+id/zota"
app:fab_showShadow="true" app:fab_showShadow="true"
@ -104,7 +124,7 @@
android:onClick="floatClick" android:onClick="floatClick"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="20dp"/> android:layout_height="20dp"/>
<aeonlabs.solutions.common.layout.fab.FloatingActionButton <bums.lunatic.launcher.view.FloatingActionButton
app:fab_label="twitter" app:fab_label="twitter"
android:id="@+id/twitter" android:id="@+id/twitter"
app:fab_showShadow="true" app:fab_showShadow="true"
@ -112,7 +132,7 @@
android:onClick="floatClick" android:onClick="floatClick"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="20dp"/> android:layout_height="20dp"/>
<aeonlabs.solutions.common.layout.fab.FloatingActionButton <bums.lunatic.launcher.view.FloatingActionButton
app:fab_label="magnet" app:fab_label="magnet"
android:id="@+id/magnet" android:id="@+id/magnet"
app:fab_showShadow="true" app:fab_showShadow="true"
@ -120,5 +140,5 @@
android:onClick="floatClick" android:onClick="floatClick"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="20dp"/> android:layout_height="20dp"/>
</aeonlabs.solutions.common.layout.fab.FloatingActionMenu> </bums.lunatic.launcher.view.FloatingActionMenu>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -23,23 +23,10 @@
android:foregroundTint="@color/finestSilver" android:foregroundTint="@color/finestSilver"
tools:ignore="ContentDescription,UseAppTint" tools:ignore="ContentDescription,UseAppTint"
android:layout_height="30dp" /> android:layout_height="30dp" />
<ImageButton <ImageButton
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
android:id="@+id/back"
android:scaleType="fitCenter"
android:adjustViewBounds="true"
android:visibility="visible"
android:background="@null"
android:src="@drawable/back_vector"
android:tint="@color/white"
android:foregroundTint="@color/white"
android:layout_width="40dp"
tools:ignore="ContentDescription"
android:layout_height="40dp" />
<ImageButton
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toLeftOf="@id/back"
android:id="@+id/vote" android:id="@+id/vote"
android:scaleType="fitCenter" android:scaleType="fitCenter"
android:adjustViewBounds="true" android:adjustViewBounds="true"
@ -65,20 +52,7 @@
tools:ignore="ContentDescription" tools:ignore="ContentDescription"
android:layout_height="40dp" android:layout_height="40dp"
/> />
<ImageButton
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toLeftOf="@id/hide"
android:id="@+id/share"
android:scaleType="fitCenter"
android:adjustViewBounds="true"
android:visibility="visible"
android:background="@null"
android:tint="@color/white"
android:foregroundTint="@color/white"
android:src="@drawable/ic_share"
android:layout_width="40dp"
tools:ignore="ContentDescription"
android:layout_height="40dp" />
<ImageButton <ImageButton
android:id="@+id/home" android:id="@+id/home"
@ -105,22 +79,7 @@
android:adjustViewBounds="true" android:adjustViewBounds="true"
tools:ignore="ContentDescription" tools:ignore="ContentDescription"
android:layout_height="40dp"/> android:layout_height="40dp"/>
<ImageButton
android:layout_marginLeft="10dp"
android:id="@+id/privateBtn"
app:layout_constraintTop_toTopOf="@id/home"
app:layout_constraintBottom_toBottomOf="@id/home"
app:layout_constraintLeft_toRightOf="@id/bookmark"
android:src="@drawable/bookmark"
android:scaleType="fitCenter"
android:background="@null"
android:layout_width="20dp"
android:tint="@color/finestSilver"
android:foregroundTint="@color/finestSilver"
android:alpha="0.2"
android:adjustViewBounds="true"
tools:ignore="ContentDescription,UseAppTint"
android:layout_height="20dp"/>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"

View File

@ -14,4 +14,87 @@
<attr name="cbd_calendar_row"/> <attr name="cbd_calendar_row"/>
</declare-styleable> </declare-styleable>
<declare-styleable name="FloatingActionButton">
<attr name="fab_colorNormal" format="color" />
<attr name="fab_colorPressed" format="color" />
<attr name="fab_colorDisabled" format="color" />
<attr name="fab_colorRipple" format="color" />
<attr name="fab_showShadow" format="boolean" />
<attr name="fab_shadowColor" format="color" />
<attr name="fab_shadowRadius" format="dimension" />
<attr name="fab_shadowXOffset" format="dimension" />
<attr name="fab_shadowYOffset" format="dimension" />
<attr name="fab_size" format="enum">
<enum name="normal" value="0" />
<enum name="mini" value="1" />
</attr>
<attr name="fab_showAnimation" format="reference" />
<attr name="fab_hideAnimation" format="reference" />
<attr name="fab_label" format="string" />
<attr name="fab_elevationCompat" format="dimension" />
<attr name="fab_progress_color" format="color" />
<attr name="fab_progress_backgroundColor" format="color" />
<attr name="fab_progress_indeterminate" format="boolean" />
<attr name="fab_progress_max" format="integer" />
<attr name="fab_progress" format="integer" />
<attr name="fab_progress_showBackground" format="boolean" />
</declare-styleable>
<declare-styleable name="FloatingActionMenu">
<attr name="menu_showShadow" format="boolean" />
<attr name="menu_buttonSpacing" format="dimension" />
<attr name="menu_labels_margin" format="dimension" />
<attr name="menu_labels_showAnimation" format="reference" />
<attr name="menu_labels_hideAnimation" format="reference" />
<attr name="menu_labels_paddingTop" format="dimension" />
<attr name="menu_labels_paddingLeft" format="dimension" />
<attr name="menu_labels_paddingRight" format="dimension" />
<attr name="menu_labels_paddingBottom" format="dimension" />
<attr name="menu_labels_padding" format="dimension" />
<attr name="menu_labels_textColor" format="reference|color" />
<attr name="menu_labels_textSize" format="dimension" />
<attr name="menu_labels_cornerRadius" format="dimension" />
<attr name="menu_labels_showShadow" format="boolean" />
<attr name="menu_labels_colorNormal" format="color" />
<attr name="menu_labels_colorPressed" format="color" />
<attr name="menu_labels_colorRipple" format="color" />
<attr name="menu_labels_position" format="enum">
<enum name="left" value="0" />
<enum name="right" value="1" />
</attr>
<attr name="menu_icon" format="reference" />
<attr name="menu_animationDelayPerItem" format="integer" />
<attr name="menu_buttonToggleAnimation" format="reference" />
<attr name="menu_labels_singleLine" format="boolean" />
<attr name="menu_labels_ellipsize" format="enum">
<enum name="none" value="0" />
<enum name="start" value="1" />
<enum name="middle" value="2" />
<enum name="end" value="3" />
<enum name="marquee" value="4" />
</attr>
<attr name="menu_labels_maxLines" format="integer" />
<attr name="menu_fab_size" format="enum">
<enum name="normal" value="0" />
<enum name="mini" value="1" />
</attr>
<attr name="menu_labels_style" format="reference" />
<attr name="menu_labels_customFont" format="string" />
<attr name="menu_shadowColor" format="color" />
<attr name="menu_shadowRadius" format="dimension" />
<attr name="menu_shadowXOffset" format="dimension" />
<attr name="menu_shadowYOffset" format="dimension" />
<attr name="menu_colorNormal" format="color" />
<attr name="menu_colorPressed" format="color" />
<attr name="menu_colorRipple" format="color" />
<attr name="menu_openDirection" format="enum">
<enum name="up" value="0" />
<enum name="down" value="1" />
</attr>
<attr name="menu_backgroundColor" format="color" />
<attr name="menu_fab_label" format="string" />
<attr name="menu_fab_show_animation" format="reference" />
<attr name="menu_fab_hide_animation" format="reference" />
</declare-styleable>
</resources> </resources>

View File

@ -39,4 +39,9 @@
<dimen name="main_top_height">30dp</dimen> <dimen name="main_top_height">30dp</dimen>
<dimen name="textview_padding">15dp</dimen> <dimen name="textview_padding">15dp</dimen>
<dimen name="setting_item_height">45dp</dimen> <dimen name="setting_item_height">45dp</dimen>
<dimen name="fab_size_normal">56dp</dimen>
<dimen name="fab_size_mini">40dp</dimen>
<dimen name="labels_text_size">14sp</dimen>
</resources> </resources>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="fab_label" type="id"/>
</resources>