...
This commit is contained in:
parent
16640559b3
commit
9f6c424e04
@ -155,6 +155,7 @@ dependencies {
|
||||
// implementation 'com.vladsch.flexmark:flexmark-all:0.64.8'
|
||||
// implementation("org.opencv:opencv-android:4.11.0")
|
||||
// build.gradle에 추가
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
|
||||
// implementation ("com.github.aeonSolutions:FloatingActionButtonMenuDrag:1.1")
|
||||
implementation("io.github.junkfood02.youtubedl-android:library:0.17.4")
|
||||
implementation("io.github.junkfood02.youtubedl-android:ffmpeg:0.17.4")
|
||||
|
||||
@ -91,8 +91,6 @@
|
||||
android:screenOrientation="userPortrait"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|screenLayout|layoutDirection|navigation"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:noHistory="true"
|
||||
android:excludeFromRecents="true"
|
||||
android:exported="false">
|
||||
|
||||
<intent-filter>
|
||||
|
||||
@ -291,7 +291,9 @@ class AppDrawerBottomSheet : BottomSheetDialogFragment() {
|
||||
if (item.type == "APP") {
|
||||
val app = realm.query<AppInfo>("pkgName == $0", item.key).first().find()
|
||||
if (app != null && !app.blockRecommend) {
|
||||
try { if(pm.getLaunchIntentForPackage(app.pkgName ?: "") != null) {
|
||||
unifiedList.add(RecommendationItem.AppItem(realm.copyFromRealm(app)))
|
||||
}} catch (e: Exception) { }
|
||||
}
|
||||
} else if (item.type == "CONTACT") {
|
||||
// 연락처 ID나 전화번호로 조회 (Log 저장 시 key가 무엇인지에 따라 다름)
|
||||
|
||||
@ -82,6 +82,40 @@ open class GeckoWeb @JvmOverloads constructor(
|
||||
|
||||
// --- 1. Properties & Initialization ---
|
||||
|
||||
// 1. 세션 상태를 저장할 SharedPreferences 키
|
||||
private val PREF_SESSION_STATE = "gecko_session_state"
|
||||
|
||||
// 2. 현재 세션 상태 저장 메서드
|
||||
fun saveCurrentSessionState() {
|
||||
|
||||
lastSessionState?.let { state ->
|
||||
// SessionState.toString()은 내부적으로 JSON 문자열을 반환합니다.
|
||||
val stateJson = state.toString()
|
||||
|
||||
context.getSharedPreferences("GeckoPrefs", Context.MODE_PRIVATE)
|
||||
.edit()
|
||||
.putString("gecko_session_state", stateJson)
|
||||
.apply()
|
||||
|
||||
Log.d("GeckoWeb", "Session State Saved: $stateJson")
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 저장된 세션 상태 복구 메서드
|
||||
fun restoreSessionState(session: GeckoSession) {
|
||||
val stateJson = context.getSharedPreferences("GeckoPrefs", Context.MODE_PRIVATE)
|
||||
.getString("gecko_session_state", null)
|
||||
|
||||
if (!stateJson.isNullOrEmpty()) {
|
||||
// 문자열에서 SessionState 객체 생성
|
||||
val state = GeckoSession.SessionState.fromString(stateJson)
|
||||
if (state != null) {
|
||||
session.restoreState(state)
|
||||
Log.d("GeckoWeb", "Session State Restored")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UI & State
|
||||
var decoViews = arrayListOf<View>()
|
||||
var progress: ProgressBar? = null
|
||||
@ -138,8 +172,8 @@ open class GeckoWeb @JvmOverloads constructor(
|
||||
override fun onLongPress(targetView: View, fingers: Int) = true
|
||||
})
|
||||
|
||||
class GKCookie { var COOKIES: String? = null }
|
||||
var mGKCookie: GKCookie? = null
|
||||
// class GKCookie { var COOKIES: String? = null }
|
||||
// var mGKCookie: GKCookie? = null
|
||||
|
||||
// Markdown/Scraping
|
||||
var markdownContents: String? = null
|
||||
@ -192,23 +226,23 @@ open class GeckoWeb @JvmOverloads constructor(
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
try {
|
||||
val request = YoutubeDLRequest(url)
|
||||
mGKCookie?.COOKIES?.let { cookieStr ->
|
||||
val cookieFile = File(context.filesDir, "cookies.txt")
|
||||
val cookies = cookieStr.split(";").mapNotNull {
|
||||
val p = it.trim().split("=", limit = 2)
|
||||
if (p.size == 2) p[0] to p[1] else null
|
||||
}.toMap()
|
||||
val expires = (System.currentTimeMillis() / 1000) + 3600 * 24 * 7
|
||||
|
||||
val content = buildString {
|
||||
appendLine("# Netscape HTTP Cookie File")
|
||||
cookies.forEach { (k, v) ->
|
||||
appendLine(".${url.toUri().host}\tTRUE\t/\tTRUE\t$expires\t$k\t$v")
|
||||
}
|
||||
}
|
||||
cookieFile.writeText(content)
|
||||
request.addOption("--cookies", cookieFile.absolutePath)
|
||||
}
|
||||
// mGKCookie?.COOKIES?.let { cookieStr ->
|
||||
// val cookieFile = File(context.filesDir, "cookies.txt")
|
||||
// val cookies = cookieStr.split(";").mapNotNull {
|
||||
// val p = it.trim().split("=", limit = 2)
|
||||
// if (p.size == 2) p[0] to p[1] else null
|
||||
// }.toMap()
|
||||
// val expires = (System.currentTimeMillis() / 1000) + 3600 * 24 * 7
|
||||
//
|
||||
// val content = buildString {
|
||||
// appendLine("# Netscape HTTP Cookie File")
|
||||
// cookies.forEach { (k, v) ->
|
||||
// appendLine(".${url.toUri().host}\tTRUE\t/\tTRUE\t$expires\t$k\t$v")
|
||||
// }
|
||||
// }
|
||||
// cookieFile.writeText(content)
|
||||
// request.addOption("--cookies", cookieFile.absolutePath)
|
||||
// }
|
||||
|
||||
val videoInfo = YoutubeDL.getInstance().getInfo(request)
|
||||
if (videoInfo != null && !videoInfo.title.isNullOrEmpty()) {
|
||||
@ -321,12 +355,14 @@ open class GeckoWeb @JvmOverloads constructor(
|
||||
}
|
||||
override fun onPageStop(session: GeckoSession, success: Boolean) {
|
||||
onPageStopCallback?.invoke(success)
|
||||
saveCurrentSessionState()
|
||||
}
|
||||
override fun onSessionStateChange(session: GeckoSession, sessionState: GeckoSession.SessionState) {
|
||||
|
||||
onSessionStateChangeCallback?.invoke(sessionState)
|
||||
}
|
||||
}
|
||||
|
||||
private var lastSessionState: GeckoSession.SessionState? = null
|
||||
// [Extension Delegates]
|
||||
private val addonManagerDelegate = object : AddonManagerDelegate {
|
||||
override fun onReady(extension: WebExtension) { mExtension = extension }
|
||||
@ -386,6 +422,7 @@ open class GeckoWeb @JvmOverloads constructor(
|
||||
private fun buildWeb() {
|
||||
getRuntime()?.let { runtime ->
|
||||
val session = GeckoSession()
|
||||
restoreSessionState(session)
|
||||
session.open(runtime)
|
||||
this.setSession(session)
|
||||
|
||||
|
||||
@ -41,12 +41,7 @@ import bums.lunatic.launcher.home.adapters.BookmarkPagerFragment
|
||||
import bums.lunatic.launcher.model.RssData
|
||||
import bums.lunatic.launcher.model.RssDataType
|
||||
import bums.lunatic.launcher.settings.SettingsActivity
|
||||
import bums.lunatic.launcher.home.tokiz.Comics
|
||||
import bums.lunatic.launcher.home.tokiz.Novels
|
||||
import bums.lunatic.launcher.home.tokiz.Perplexity
|
||||
import bums.lunatic.launcher.home.tokiz.TokiFragment
|
||||
import bums.lunatic.launcher.home.tokiz.Webtoons
|
||||
import bums.lunatic.launcher.home.tokiz.YouTube
|
||||
import bums.lunatic.launcher.utils.Blog
|
||||
import bums.lunatic.launcher.utils.beforeDay
|
||||
import bums.lunatic.launcher.workers.WorkersDb
|
||||
@ -63,6 +58,7 @@ import org.mozilla.geckoview.ExperimentDelegate
|
||||
import org.mozilla.geckoview.GeckoResult
|
||||
import org.mozilla.geckoview.GeckoRuntime
|
||||
import org.mozilla.geckoview.GeckoRuntimeSettings
|
||||
import java.io.File
|
||||
|
||||
|
||||
open class NeoRssActivity : CommonActivity() {
|
||||
@ -116,7 +112,7 @@ open class NeoRssActivity : CommonActivity() {
|
||||
var onExit = false
|
||||
var lastAction = MotionEvent.ACTION_HOVER_EXIT
|
||||
override fun dispatchKeyEvent(ev: KeyEvent): Boolean {
|
||||
val currentFragment = supportFragmentManager.findFragmentById(R.id.fragment_container)
|
||||
Blog.LOGE("dispatchKeyEvent >>> ${ev}")
|
||||
if (ev?.device?.name?.contains("SM-031N Mouse") == true) {
|
||||
when(ev.action) {
|
||||
ACTION_UP -> {
|
||||
@ -162,16 +158,16 @@ open class NeoRssActivity : CommonActivity() {
|
||||
}
|
||||
else {
|
||||
val currentFragment = supportFragmentManager.findFragmentById(R.id.fragment_container)
|
||||
when(currentFragment) {
|
||||
is Novels -> {
|
||||
Blog.LOGE("currentFragment >>> ${currentFragment} ${currentFragment is TokiFragment && currentFragment.isbooktoki()}")
|
||||
if (currentFragment is TokiFragment && currentFragment.isbooktoki()) {
|
||||
if(MotionEvent.ACTION_UP.equals(ev?.action ?: MotionEvent.ACTION_CANCEL) == true) {
|
||||
return when (ev.keyCode) {
|
||||
KeyEvent.KEYCODE_VOLUME_DOWN -> {
|
||||
if(currentFragment is Novels){ currentFragment.actionNextEvent() }
|
||||
if(currentFragment is TokiFragment){ currentFragment.actionNextEvent() }
|
||||
true
|
||||
}
|
||||
KeyEvent.KEYCODE_VOLUME_UP -> {
|
||||
if(currentFragment is Novels){ currentFragment.actionPrevEvent() }
|
||||
if(currentFragment is TokiFragment){ currentFragment.actionPrevEvent() }
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
@ -190,8 +186,7 @@ open class NeoRssActivity : CommonActivity() {
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> return super.dispatchKeyEvent(ev)
|
||||
}
|
||||
else { return super.dispatchKeyEvent(ev) }
|
||||
}
|
||||
return super.dispatchKeyEvent(ev)
|
||||
}
|
||||
@ -293,67 +288,6 @@ open class NeoRssActivity : CommonActivity() {
|
||||
showContents(v.id)
|
||||
}
|
||||
|
||||
// override fun onNewIntent(intent: Intent) {
|
||||
// Blog.LOGE("onNewIntent intent >> ${intent}")
|
||||
// if(intent?.action?.equals(Intent.ACTION_SEND) == true &&
|
||||
// intent?.hasExtra(Intent.EXTRA_TEXT) == true) {
|
||||
// intent?.getStringExtra(Intent.EXTRA_TEXT)?.let {
|
||||
// if(it.startsWith("http") == false) {
|
||||
// it.split("http").forEach { string ->
|
||||
// if(string.startsWith("http")) {
|
||||
// try {
|
||||
// string.toUri()?.let { uri ->
|
||||
// Blog.LOGE("onNewIntent string uri.lastPathSegment >>>>> ${uri.host}")
|
||||
// Blog.LOGE("onNewIntent string uri.lastPathSegment >>>>> ${uri.lastPathSegment}")
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// try {
|
||||
// it.toUri()?.let { uri ->
|
||||
// Blog.LOGE("onNewIntent it uri.lastPathSegment >>>>> ${uri.host}")
|
||||
// Blog.LOGE("onNewIntent it uri.lastPathSegment >>>>> ${uri.lastPathSegment}")
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } else if (intent?.action == Intent.ACTION_WEB_SEARCH) {
|
||||
// openWithIntent(intent)
|
||||
// } else {
|
||||
// Blog.LOGE("onNewIntent intent?.hasExtra >> ${intent?.hasExtra(Intent.EXTRA_STREAM)}")
|
||||
//
|
||||
//
|
||||
// if (intent?.action?.equals(Intent.ACTION_MAIN) == true && intent.categories.contains(
|
||||
// Intent.CATEGORY_HOME
|
||||
// ) && intent.hasExtra("android.intent.extra.EXTRA_START_REASON") && intent.getStringExtra(
|
||||
// "android.intent.extra.EXTRA_START_REASON"
|
||||
// ).equals("startDockOrHome")
|
||||
// ) {
|
||||
//
|
||||
// } else {
|
||||
// intent?.extras?.keySet()?.forEach {
|
||||
// try {
|
||||
// Blog.LOGE(
|
||||
// "onNewIntent :: key >> ${it} :: value >> ${
|
||||
// intent?.extras?.getString(
|
||||
// it
|
||||
// )
|
||||
// }"
|
||||
// )
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// super.onNewIntent(intent)
|
||||
// }
|
||||
|
||||
private fun openWithIntent(intent: Intent){
|
||||
Blog.LOGE("intent >> ${intent}")
|
||||
@ -528,7 +462,13 @@ open class NeoRssActivity : CommonActivity() {
|
||||
private fun initGeckoRuntime() {
|
||||
if (sRuntime == null) {
|
||||
try {
|
||||
val profileDir = File(this.filesDir, "geckoview_profile")
|
||||
if (!profileDir.exists()) profileDir.mkdirs()
|
||||
|
||||
sRuntime = GeckoRuntime.create(this, GeckoRuntimeSettings.Builder()
|
||||
.configFilePath(profileDir.absolutePath)
|
||||
.aboutConfigEnabled(true)
|
||||
.javaScriptEnabled(true)
|
||||
.extensionsProcessEnabled(true)
|
||||
.extensionsWebAPIEnabled(true)
|
||||
.experimentDelegate(experimentDelegate)
|
||||
@ -559,16 +499,9 @@ open class NeoRssActivity : CommonActivity() {
|
||||
sRuntime = null
|
||||
} catch (e: Exception) { e.printStackTrace() }
|
||||
|
||||
// appWidgetHost?.stopListening() // 이 줄은 제거하고 onStop으로 이동
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onUserLeaveHint() {
|
||||
|
||||
showContents(R.id.close)
|
||||
|
||||
super.onUserLeaveHint()
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O_MR1)
|
||||
override fun onResume() {
|
||||
@ -605,12 +538,12 @@ open class NeoRssActivity : CommonActivity() {
|
||||
currentFragment.doNextPage()
|
||||
}
|
||||
}
|
||||
is YouTube -> {
|
||||
currentFragment.back()
|
||||
}
|
||||
is Novels -> {
|
||||
currentFragment.actionNextEvent(false)
|
||||
}
|
||||
// is YouTube -> {
|
||||
// currentFragment.back()
|
||||
// }
|
||||
// is Novels -> {
|
||||
// currentFragment.actionNextEvent(false)
|
||||
// }
|
||||
else -> {
|
||||
showContents(R.id.close)
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -33,7 +33,6 @@ import androidx.fragment.app.Fragment
|
||||
import bums.lunatic.launcher.R
|
||||
import bums.lunatic.launcher.databinding.BooktokiBinding
|
||||
import bums.lunatic.launcher.home.GeckoWeb
|
||||
import bums.lunatic.launcher.home.GeckoWeb.GKCookie
|
||||
import bums.lunatic.launcher.home.GeckoWeb.JxEvent
|
||||
import bums.lunatic.launcher.home.NeoRssActivity
|
||||
import bums.lunatic.launcher.home.NeoRssActivity.Companion.getRuntime
|
||||
@ -224,6 +223,9 @@ class TokiFragment : Fragment(), PagedTextViewInterface {
|
||||
}
|
||||
}
|
||||
|
||||
fun isbooktoki() : Boolean {
|
||||
return webcontentsName.contains("booktoki")
|
||||
}
|
||||
override fun onSwipeLeft(count: Int) {
|
||||
if (!enableGestures) return
|
||||
Blog.LOGD(log = "onSwipeLeft ${count}")
|
||||
@ -1060,7 +1062,7 @@ class TokiFragment : Fragment(), PagedTextViewInterface {
|
||||
view.visibility = VISIBLE
|
||||
binding.menuWeb.visibility = GONE
|
||||
}
|
||||
view.forceUpdateUI()
|
||||
// view.forceUpdateUI()
|
||||
lastedUrl?.let {
|
||||
Uri.parse(it)?.let { uri ->
|
||||
uri.path?.let {
|
||||
|
||||
@ -1,336 +0,0 @@
|
||||
//package bums.lunatic.launcher.home.tokiz.view
|
||||
//
|
||||
//import android.annotation.SuppressLint
|
||||
//import android.content.Context
|
||||
//import android.content.Intent
|
||||
//import android.os.Build
|
||||
//import android.util.AttributeSet
|
||||
//import android.view.MotionEvent
|
||||
//import android.view.PointerIcon
|
||||
//import android.view.View
|
||||
//import androidx.core.net.toUri
|
||||
//import androidx.core.view.isVisible
|
||||
//import bums.lunatic.launcher.R
|
||||
//import bums.lunatic.launcher.helpers.ForeGroundService
|
||||
//import bums.lunatic.launcher.helpers.ForeGroundService.Companion.ACTION_VIDEO_DOWNLOAD
|
||||
//import bums.lunatic.launcher.helpers.ForeGroundService.Companion.EXTRA_TARGET_URL
|
||||
//import bums.lunatic.launcher.utils.Blog
|
||||
//import bums.lunatic.launcher.utils.SimpleFingerGestures
|
||||
//import com.yausername.youtubedl_android.YoutubeDL
|
||||
//import com.yausername.youtubedl_android.YoutubeDLRequest
|
||||
//import kotlinx.coroutines.CoroutineScope
|
||||
//import kotlinx.coroutines.Dispatchers
|
||||
//import kotlinx.coroutines.launch
|
||||
//import org.mozilla.gecko.util.ThreadUtils.runOnUiThread
|
||||
//import org.mozilla.geckoview.GeckoView
|
||||
//import java.io.File
|
||||
//import java.util.Base64
|
||||
//import kotlin.collections.iterator
|
||||
//
|
||||
//enum class JxEvent {
|
||||
// SCROLL_UP,
|
||||
// SCROLL_DOWN,
|
||||
// SWIPE_LEFT,
|
||||
// SWIPE_RIGHT,
|
||||
// ON_CLICK,
|
||||
//}
|
||||
//typealias JxInteface = (JxEvent)->Unit
|
||||
//open class BWebview : GeckoView {
|
||||
// var decoViews = arrayListOf<View>()
|
||||
// @SuppressLint("ClickableViewAccessibility")
|
||||
// constructor(context: Context?) : super(context) {
|
||||
// this.setOnTouchListener { v, event ->
|
||||
// if (event.device.name?.contains(
|
||||
// "JX-12",
|
||||
// true
|
||||
// ) == true || event.device.name?.equals("J06", true) == true
|
||||
// ) {
|
||||
// return@setOnTouchListener mSimpleFingerGestures.onTouch(v, event)
|
||||
// } else {
|
||||
// return@setOnTouchListener super.onTouchEvent(event)
|
||||
// }
|
||||
// }
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
// val nullCursor = PointerIcon.getSystemIcon(context!!, PointerIcon.TYPE_NULL)
|
||||
// this.setPointerIcon(nullCursor)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// @SuppressLint("ClickableViewAccessibility")
|
||||
// constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
|
||||
// this.setOnTouchListener { v,event ->
|
||||
// if (event.device.name?.contains("JX-12",true) == true|| event.device.name?.equals("J06",true) == true) {
|
||||
// return@setOnTouchListener mSimpleFingerGestures.onTouch(v,event)
|
||||
// } else {
|
||||
// return@setOnTouchListener super.onTouchEvent(event)
|
||||
// }
|
||||
// }
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
// val nullCursor = PointerIcon.getSystemIcon(context!!, PointerIcon.TYPE_NULL)
|
||||
// this.setPointerIcon(nullCursor)
|
||||
// }
|
||||
// }
|
||||
// fun videoDlownLoad(videoUrl : String) {
|
||||
// val actionIntent = Intent(context, ForeGroundService::class.java).apply {
|
||||
// action = ACTION_VIDEO_DOWNLOAD
|
||||
// putExtra(EXTRA_TARGET_URL, videoUrl) // 전달할 데이터
|
||||
// }
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
// context.startForegroundService(actionIntent)
|
||||
// } else {
|
||||
// context.startService(actionIntent)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// class GKCookie {
|
||||
// var COOKIES : String? = null
|
||||
// }
|
||||
//
|
||||
// var mGKCookie : GKCookie? = null
|
||||
//
|
||||
// fun checkIfDownloadable(url: String) {
|
||||
// CoroutineScope(Dispatchers.Main).launch {
|
||||
// runOnUiThread {
|
||||
// decoViews.filter { it.id == R.id.dl_video }.firstOrNull()?.let {
|
||||
// it.setOnClickListener {}
|
||||
// it.visibility = GONE
|
||||
// }}}
|
||||
// Blog.LOGE("checkIfDownloadable ${url}")
|
||||
// CoroutineScope(Dispatchers.IO).launch {
|
||||
// try {
|
||||
// var request = YoutubeDLRequest(url)
|
||||
// (mGKCookie?.COOKIES)?.let{
|
||||
// Blog.LOGE(it)
|
||||
// val cookies = it.split(";")
|
||||
// .map { it.trim() }
|
||||
// .mapNotNull {
|
||||
// val parts = it.split("=", limit = 2)
|
||||
// if (parts.size == 2) parts[0] to parts[1] else null
|
||||
// }
|
||||
// .toMap()
|
||||
// val expires = (System.currentTimeMillis() / 1000) + 3600 * 24 * 7 // 일주일 후 만료 예시
|
||||
//
|
||||
// val cookieFileContent = buildString {
|
||||
// appendLine("# Netscape HTTP Cookie File")
|
||||
// for ((name, value) in cookies) {
|
||||
// appendLine(".${url.toUri().host}\tTRUE\t/\tTRUE\t$expires\t$name\t$value")
|
||||
// }
|
||||
// }
|
||||
// val cookieFile = File(context.filesDir, "cookies.txt")
|
||||
// cookieFile.writeText(cookieFileContent)
|
||||
// request.addOption("--cookies", cookieFile.absolutePath)
|
||||
// }
|
||||
//
|
||||
// val videoInfo = YoutubeDL.getInstance().getInfo(request)
|
||||
// // videoInfo 가 null 아니고, 필요한 키(예: title, url 등)가 있으면 다운로드 가능
|
||||
// Blog.LOGE("checkIfDownloadable ${url}\n videoInfo : ${videoInfo}")
|
||||
// var canVideoDown = videoInfo != null && !videoInfo.title.isNullOrEmpty()
|
||||
// CoroutineScope(Dispatchers.Main).launch {
|
||||
// runOnUiThread {
|
||||
// decoViews.filter { it.id == R.id.dl_video }.firstOrNull()?.let {
|
||||
// it.setOnClickListener {
|
||||
// videoDlownLoad(url)
|
||||
// }
|
||||
// it.visibility = if (canVideoDown){
|
||||
// VISIBLE
|
||||
// } else{
|
||||
// GONE
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// Blog.LOGE("checkIfDownloadable ${url} ${e}")
|
||||
// CoroutineScope(Dispatchers.Main).launch {
|
||||
// runOnUiThread {
|
||||
// decoViews.filter { it.id == R.id.dl_video }.firstOrNull()?.let {
|
||||
// it.setOnClickListener {}
|
||||
// it.visibility = GONE
|
||||
// }}}
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// val mSimpleFingerGestures = SimpleFingerGestures(omfgl = object : SimpleFingerGestures.OnFingerGestureListener{
|
||||
//
|
||||
// override fun onSwipeUp(
|
||||
// targetView: View,
|
||||
// fingers: Int,
|
||||
// gestureDuration: Long,
|
||||
// gestureDistance: Double
|
||||
// ): Boolean {
|
||||
// Blog.LOGE("")
|
||||
// jxInteface?.invoke(JxEvent.SCROLL_UP )
|
||||
// return true
|
||||
// }
|
||||
//
|
||||
// override fun onSwipeDown(
|
||||
// targetView: View,
|
||||
// fingers: Int,
|
||||
// gestureDuration: Long,
|
||||
// gestureDistance: Double
|
||||
// ): Boolean {
|
||||
// Blog.LOGE("")
|
||||
// jxInteface?.invoke(JxEvent.SCROLL_DOWN)
|
||||
// return true
|
||||
// }
|
||||
//
|
||||
// override fun onSwipeLeft(
|
||||
// targetView: View,
|
||||
// fingers: Int,
|
||||
// gestureDuration: Long,
|
||||
// gestureDistance: Double
|
||||
// ): Boolean {
|
||||
// Blog.LOGE("")
|
||||
// jxInteface?.invoke(JxEvent.SWIPE_LEFT)
|
||||
// return true
|
||||
// }
|
||||
//
|
||||
// override fun onSwipeRight(
|
||||
// targetView: View,
|
||||
// fingers: Int,
|
||||
// gestureDuration: Long,
|
||||
// gestureDistance: Double
|
||||
// ): Boolean {
|
||||
// Blog.LOGE("")
|
||||
// jxInteface?.invoke(JxEvent.SWIPE_RIGHT)
|
||||
// return true
|
||||
// }
|
||||
//
|
||||
// override fun onPinch(
|
||||
// targetView: View,
|
||||
// fingers: Int,
|
||||
// gestureDuration: Long,
|
||||
// gestureDistance: Double
|
||||
// ): Boolean {
|
||||
// Blog.LOGE("onPinch")
|
||||
// return true
|
||||
// }
|
||||
//
|
||||
// override fun onUnpinch(
|
||||
// targetView: View,
|
||||
// fingers: Int,
|
||||
// gestureDuration: Long,
|
||||
// gestureDistance: Double
|
||||
// ): Boolean {
|
||||
// Blog.LOGE("")
|
||||
// return true
|
||||
// }
|
||||
//
|
||||
// override fun onDoubleTap(
|
||||
// targetView: View,
|
||||
// fingers: Int
|
||||
// ): Boolean {
|
||||
// Blog.LOGE("")
|
||||
// return true
|
||||
// }
|
||||
//
|
||||
// override fun onLongPress(
|
||||
// targetView: View,
|
||||
// fingers: Int
|
||||
// ): Boolean {
|
||||
// Blog.LOGE("onLongPress")
|
||||
// return true
|
||||
// }
|
||||
//
|
||||
// override fun onClick(
|
||||
// targetView: View,
|
||||
// fingers: Int
|
||||
// ): Boolean {
|
||||
// Blog.LOGE("onClick")
|
||||
// jxInteface?.invoke(JxEvent.ON_CLICK)
|
||||
// return true
|
||||
// }
|
||||
//
|
||||
//
|
||||
// })
|
||||
// companion object {
|
||||
// var currentRetryCount = 0
|
||||
// }
|
||||
//
|
||||
// var jxInteface : JxInteface? = null
|
||||
//
|
||||
// var lastDomain : String = ""
|
||||
//
|
||||
// open fun loadUrl(url: String, param : String? = null) {
|
||||
// var nUrl = url
|
||||
// Blog.LOGE("url >>>> ${url}")
|
||||
// if (url.endsWith("=")) {
|
||||
// nUrl = String(Base64.getMimeDecoder().decode(url.toByteArray()))
|
||||
// param?.let {
|
||||
// nUrl = nUrl.plus(param)
|
||||
// }
|
||||
// } else if (url.startsWith("http") == false) {
|
||||
// nUrl = lastDomain
|
||||
// }
|
||||
// if (this.isVisible == false) {
|
||||
// this.visibility = VISIBLE
|
||||
// }
|
||||
// Blog.LOGE("nUrl >>>> ${nUrl}")
|
||||
//
|
||||
//
|
||||
// nUrl?.let { url ->
|
||||
// if (url.split("//").size > 1) {
|
||||
// url.replace("//","/").replace("https:/","https://").let {
|
||||
// Blog.LOGE("url >> ${url} , it >>> ${it}")
|
||||
// this.session?.loadUri(it)
|
||||
// }
|
||||
// } else {
|
||||
// this.session?.loadUri(url)
|
||||
// }
|
||||
// }
|
||||
// currentRetryCount = 0;
|
||||
// }
|
||||
// private var lastX = 0f
|
||||
// private var lastY = 0f
|
||||
//
|
||||
//
|
||||
// override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||
// Blog.LOGE("event.device.name >>> ${event.device.name}")
|
||||
// if (event.device.name?.contains("JX-12",true) == true || event.device.name?.equals("J06",true) == true) {
|
||||
// Blog.LOGE("BWebview onTouchEvent $event")
|
||||
// when (event.action) {
|
||||
// MotionEvent.ACTION_DOWN -> {
|
||||
// lastX = event.x
|
||||
// lastY = event.y
|
||||
// return true
|
||||
// }
|
||||
//
|
||||
// MotionEvent.ACTION_MOVE -> {
|
||||
// val deltaX = event.x - lastX
|
||||
// val deltaY = event.y - lastY
|
||||
// // 상하 이동이 더 크면(즉, 거의 수직 이동이면)만 처리
|
||||
// if (Math.abs(deltaY) > Math.abs(deltaX)) {
|
||||
// // 원하는 감도 적용
|
||||
// val scrollFactor = 0.1f
|
||||
//// scrollBy(0, (-deltaY * scrollFactor).toInt())
|
||||
//
|
||||
// jxInteface?.invoke(if ((-deltaY * scrollFactor).toInt() > 0){
|
||||
// JxEvent.SCROLL_DOWN
|
||||
// } else {
|
||||
// JxEvent.SCROLL_UP
|
||||
// })
|
||||
// lastY = event.y
|
||||
// lastX = event.x
|
||||
// Blog.LOGE("return true for scroll")
|
||||
// return true
|
||||
// }
|
||||
// // 좌우 이동은 무시
|
||||
// lastY = event.y
|
||||
// lastX = event.x
|
||||
// Blog.LOGE("return false")
|
||||
// return false
|
||||
// }
|
||||
//
|
||||
// else -> {
|
||||
// Blog.LOGE("call super")
|
||||
// return super.onTouchEvent(event)
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// return super.onTouchEvent(event)
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@ -3,11 +3,13 @@ package bums.lunatic.launcher.home.tokiz.view
|
||||
import android.annotation.TargetApi
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Typeface
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.text.Layout
|
||||
import android.text.StaticLayout
|
||||
import android.text.TextPaint
|
||||
import android.util.AttributeSet
|
||||
import android.util.TypedValue
|
||||
import android.view.View
|
||||
@ -19,8 +21,10 @@ import bums.lunatic.launcher.R
|
||||
import bums.lunatic.launcher.home.tokiz.TouchArea
|
||||
import bums.lunatic.launcher.utils.Blog
|
||||
import bums.lunatic.launcher.utils.SimpleFingerGestures
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlin.math.min
|
||||
|
||||
|
||||
@ -33,248 +37,6 @@ interface PagedTextViewInterface {
|
||||
fun onSwipeUp(touchCount : Int)
|
||||
fun onLongClick()
|
||||
}
|
||||
class PagedTextView : AppCompatTextView {
|
||||
|
||||
private var needPaginate = false
|
||||
private var isPaginating = false
|
||||
private val pageList = arrayListOf<CharSequence>()
|
||||
private var pageIndex: Int = 0
|
||||
private var pageHeight: Int = 0
|
||||
private var originalText: CharSequence = ""
|
||||
|
||||
var mPagedTextGenerateInterface : PagedTextGenerateInterface? = null
|
||||
|
||||
|
||||
constructor(context: Context?) : super(context!!){initView(context)}
|
||||
|
||||
constructor(context: Context?, attrs: AttributeSet?) : super(context!!, attrs){initView(context)}
|
||||
|
||||
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context!!, attrs, defStyleAttr){initView(context)}
|
||||
|
||||
fun initView(context: Context?){
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
fun size(): Int = pageList.size
|
||||
fun current() : Int = pageIndex
|
||||
|
||||
fun doPrev() {
|
||||
if (pageIndex > 0 )
|
||||
pageIndex = pageIndex - 1
|
||||
setPageText()
|
||||
}
|
||||
|
||||
fun doNext() {
|
||||
if (pageIndex < pageList.size)
|
||||
pageIndex = pageIndex + 1
|
||||
setPageText()
|
||||
}
|
||||
|
||||
fun next(index: Int) {
|
||||
pageIndex = index
|
||||
setPageText()
|
||||
}
|
||||
|
||||
private fun setPageText() {
|
||||
if(pageList.size > 0) {
|
||||
isPaginating = true
|
||||
text = pageList[pageIndex]
|
||||
isPaginating = false
|
||||
}
|
||||
}
|
||||
|
||||
fun setTxtF(text: CharSequence?) {
|
||||
needPaginate = true
|
||||
this.setText(text , null)
|
||||
}
|
||||
|
||||
override fun setText(text: CharSequence?, type: BufferType?) {
|
||||
if (!isPaginating) {
|
||||
needPaginate = true
|
||||
originalText = text ?: ""
|
||||
}
|
||||
super.setText(text, type)
|
||||
}
|
||||
|
||||
|
||||
|
||||
override fun setTextSize(size: Float) {
|
||||
setTextSize(TypedValue.COMPLEX_UNIT_SP, size)
|
||||
}
|
||||
|
||||
override fun setTextSize(unit: Int, size: Float) {
|
||||
super.setTextSize(unit, size)
|
||||
paint.textSize = TypedValue.applyDimension(unit, size, context.resources.getDisplayMetrics())
|
||||
needPaginate = true
|
||||
}
|
||||
|
||||
override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) {
|
||||
super.setPadding(left, top, right, bottom)
|
||||
needPaginate = true
|
||||
}
|
||||
|
||||
override fun setPaddingRelative(start: Int, top: Int, end: Int, bottom: Int) {
|
||||
super.setPaddingRelative(start, top, end, bottom)
|
||||
needPaginate = true
|
||||
}
|
||||
|
||||
override fun setTextScaleX(size: Float) {
|
||||
if (size != textScaleX) {
|
||||
needPaginate = true
|
||||
}
|
||||
super.setTextScaleX(size)
|
||||
}
|
||||
|
||||
override fun setTypeface(tf: Typeface?) {
|
||||
if (typeface != null && tf != typeface) {
|
||||
needPaginate = true
|
||||
paint.typeface = tf
|
||||
}
|
||||
super.setTypeface(tf)
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
override fun setLetterSpacing(letterSpacing: Float) {
|
||||
if (letterSpacing != this.letterSpacing) {
|
||||
needPaginate = true
|
||||
}
|
||||
super.setLetterSpacing(letterSpacing)
|
||||
}
|
||||
|
||||
override fun setHorizontallyScrolling(whether: Boolean) {
|
||||
super.setHorizontallyScrolling(false)
|
||||
}
|
||||
|
||||
override fun setLineSpacing(add: Float, mult: Float) {
|
||||
if (add != lineSpacingExtra || mult != lineSpacingMultiplier) {
|
||||
needPaginate = true
|
||||
}
|
||||
super.setLineSpacing(add, mult)
|
||||
}
|
||||
|
||||
override fun setMaxLines(maxLines: Int) {
|
||||
if (maxLines != this.maxLines) {
|
||||
needPaginate = true
|
||||
}
|
||||
|
||||
super.setMaxLines(maxLines)
|
||||
}
|
||||
|
||||
override fun setLines(lines: Int) {
|
||||
super.setLines(lines)
|
||||
|
||||
if (lines != this.lineCount) {
|
||||
needPaginate = true
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
|
||||
super.onSizeChanged(w, h, oldw, oldh)
|
||||
pageHeight = h - (paddingTop + paddingBottom) // 마진 제외
|
||||
}
|
||||
|
||||
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
|
||||
super.onLayout(changed, left, top, right, bottom)
|
||||
Blog.LOGD(log = "onLayout>> ${this::class.java.name} changed >> ${changed}")
|
||||
if (changed || needPaginate) {
|
||||
paginate()
|
||||
setPageText()
|
||||
needPaginate = false
|
||||
}
|
||||
|
||||
}
|
||||
fun doUpdate() {
|
||||
if (needPaginate && layout != null) {
|
||||
paginate()
|
||||
setPageText()
|
||||
needPaginate = false
|
||||
}
|
||||
}
|
||||
private fun paginate() {
|
||||
if (layout != null) {
|
||||
MainScope().launch {
|
||||
pageList.clear()
|
||||
// Blog.LOGD(log = "paginate>> ${this::class.java.name} && ${layout.text}")
|
||||
val layout = from(layout)
|
||||
val lines = if(min(maxLines, layout.lineCount) > 10) {min(maxLines, layout.lineCount) - 1} else {min(maxLines, layout.lineCount)}
|
||||
var startOffset = 0
|
||||
val heightWithoutPaddings = pageHeight //- (marginTop + marginBottom + paddingTop + paddingBottom)
|
||||
var height = heightWithoutPaddings
|
||||
|
||||
for (i in 0 until lines) {
|
||||
if (height < layout.getLineBottom(i)) {
|
||||
pageList.add(
|
||||
layout.text.subSequence(startOffset, layout.getLineStart(i))
|
||||
)
|
||||
startOffset = layout.getLineStart(i)
|
||||
height = layout.getLineTop(i) + heightWithoutPaddings
|
||||
}
|
||||
|
||||
if (i == lines - 1) {
|
||||
pageList.add(
|
||||
if(layout.lineCount > i) {
|
||||
layout.text.subSequence(startOffset, layout.getLineEnd(i + 1))
|
||||
} else {
|
||||
layout.text.subSequence(startOffset, layout.getLineEnd(i))
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
mPagedTextGenerateInterface?.completePagination(pageList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun from(layout: Layout): Layout =
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||
@Suppress("DEPRECATION")
|
||||
StaticLayout(
|
||||
originalText,
|
||||
paint,
|
||||
layout.width - paddingLeft - paddingRight, // margin 제외
|
||||
layout.alignment,
|
||||
lineSpacingMultiplier,
|
||||
lineSpacingExtra,
|
||||
includeFontPadding
|
||||
)
|
||||
} else {
|
||||
StaticLayout.Builder
|
||||
.obtain(
|
||||
originalText, 0, originalText.length, paint,
|
||||
(layout.width - paddingLeft - paddingRight)
|
||||
)
|
||||
.setAlignment(layout.alignment)
|
||||
.setLineSpacing(lineSpacingExtra, lineSpacingMultiplier)
|
||||
.setIncludePad(includeFontPadding)
|
||||
.setUseLineSpacingFromFallbacks()
|
||||
.setBreakStrategy(breakStrategy)
|
||||
.setHyphenationFrequency(hyphenationFrequency)
|
||||
.setMaxLines(maxLines)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun StaticLayout.Builder.setUseLineSpacingFromFallbacks(): StaticLayout.Builder {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
this.setUseLineSpacingFromFallbacks(isFallbackLineSpacing)
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
private fun StaticLayout.Builder.setJustificationMode(): StaticLayout.Builder {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
this.setJustificationMode(justificationMode)
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interface PagedTextGenerateInterface {
|
||||
fun completePagination(pageList: ArrayList<CharSequence>)
|
||||
@ -297,26 +59,95 @@ class PagedTextLayout : ConstraintLayout , PagedTextGenerateInterface {
|
||||
var mainTextView : TextView? = null
|
||||
var sencondTextView : TextView? = null
|
||||
var demp : View? = null
|
||||
var hiddenTextView : PagedTextView? = null
|
||||
// var hiddenTextView : PagedTextView? = null
|
||||
var guideLine : Guideline? = null
|
||||
var pageList: ArrayList<CharSequence>? = null
|
||||
var pageList = mutableListOf<CharSequence>()
|
||||
var summaryText : String = ""
|
||||
var text : String = ""
|
||||
set(new) {
|
||||
// Blog.LOGE("field >> ${field}")
|
||||
// Blog.LOGE("new >> ${new}")
|
||||
field = new
|
||||
val summary = new.replace(" " ,"").replace("\n" ,"").substring(0,Math.min(30,new.length))
|
||||
if (summary.equals(summaryText)) {
|
||||
if (summary.equals(summaryText) && summaryText.length > 100) {
|
||||
|
||||
} else {
|
||||
// Blog.LOGE("field >> ${field}")
|
||||
hiddenTextView?.setTxtF(field)
|
||||
hiddenTextView?.visibility = VISIBLE
|
||||
if (field.length > 0) {
|
||||
post {
|
||||
if (width > 0 && height > 0) {
|
||||
MainScope().launch {
|
||||
pageList.clear()
|
||||
val contentWidth =
|
||||
mainTextView!!.width - (mainTextView!!.paddingLeft + mainTextView!!.paddingRight)
|
||||
val contentHeight =
|
||||
mainTextView!!.height - (mainTextView!!.paddingTop + mainTextView!!.paddingBottom)
|
||||
val pages = paginateAsync(text, contentWidth, contentHeight)
|
||||
pageList.addAll(pages)
|
||||
Blog.LOGE("pages >>> ${pages.size}")
|
||||
setPageBy(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
summaryText = summary
|
||||
}
|
||||
suspend fun paginateAsync(text: CharSequence, width: Int, height: Int): List<CharSequence> = withContext(Dispatchers.Default) {
|
||||
val resultPages = ArrayList<CharSequence>()
|
||||
val paint = mainTextView?.paint ?: TextPaint()
|
||||
val lineSpacingMult = mainTextView?.lineSpacingMultiplier ?: 1.0f
|
||||
val lineSpacingAdd = mainTextView?.lineSpacingExtra ?: 1.0f
|
||||
val letterSpacing = mainTextView?.letterSpacing ?: 1.0f
|
||||
val includePad = false
|
||||
Blog.LOGE("text ${text.length}, width $width, height $height")
|
||||
// 1. 전체 텍스트에 대한 StaticLayout 생성 (API 버전에 따른 분기 처리 권장)
|
||||
val layout = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
StaticLayout.Builder.obtain(text, 0, text.length, paint, width)
|
||||
.setAlignment(Layout.Alignment.ALIGN_NORMAL)
|
||||
.setLineSpacing(lineSpacingAdd, lineSpacingMult)
|
||||
.setIncludePad(includePad)
|
||||
.build()
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
StaticLayout(text, paint, width, Layout.Alignment.ALIGN_NORMAL, lineSpacingMult, lineSpacingAdd, includePad)
|
||||
}
|
||||
|
||||
val totalLines = layout.lineCount
|
||||
var startLine = 0
|
||||
var startOffset = 0
|
||||
|
||||
// 2. 라인 정보를 순회하며 높이 계산
|
||||
while (startLine < totalLines) {
|
||||
// 현재 페이지의 시작 y 좌표
|
||||
val pageTopY = layout.getLineTop(startLine)
|
||||
// 현재 페이지가 끝날 수 있는 최대 y 좌표
|
||||
val targetBottomY = pageTopY + height
|
||||
|
||||
// 이 페이지에 들어갈 수 있는 마지막 라인 찾기
|
||||
var endLine = layout.getLineForVertical(targetBottomY)
|
||||
|
||||
// getLineForVertical은 정확한 좌표가 없으면 마지막 라인을 반환하므로 검증 필요
|
||||
if (layout.getLineBottom(endLine) > targetBottomY) {
|
||||
endLine--
|
||||
}
|
||||
|
||||
// 한 줄도 못 들어가는 경우(폰트가 뷰보다 큰 경우 등) 방어 코드
|
||||
if (endLine < startLine) endLine = startLine
|
||||
|
||||
// 페이지 범위의 텍스트 추출
|
||||
// endLine의 끝 오프셋을 가져옴
|
||||
val endOffset = layout.getLineEnd(endLine)
|
||||
|
||||
// 텍스트 자르기 (subSequence는 메모리 복사를 최소화함)
|
||||
if (startOffset < endOffset) {
|
||||
resultPages.add(text.subSequence(startOffset, endOffset))
|
||||
}
|
||||
|
||||
// 다음 페이지 준비
|
||||
startOffset = endOffset
|
||||
startLine = endLine + 1
|
||||
}
|
||||
|
||||
return@withContext resultPages
|
||||
}
|
||||
private val hanler = Handler()
|
||||
var mPagedTextViewInterface : PagedTextViewInterface? = null
|
||||
val touchTimeover = Runnable {
|
||||
@ -328,11 +159,8 @@ class PagedTextLayout : ConstraintLayout , PagedTextGenerateInterface {
|
||||
inflate(context, R.layout.layout_textviewer, this)
|
||||
mainTextView = findViewById(R.id.first_view)
|
||||
sencondTextView = findViewById(R.id.sencond_view)
|
||||
demp = findViewById(R.id.demp)
|
||||
currentPageTextView = findViewById(R.id.current_page)
|
||||
|
||||
hiddenTextView = findViewById(R.id.hidden_view)
|
||||
hiddenTextView?.mPagedTextGenerateInterface = this
|
||||
currentPageTextView?.text = ""
|
||||
hanler.removeCallbacks(touchTimeover)
|
||||
setOnLongClickListener { v ->
|
||||
@ -450,8 +278,7 @@ class PagedTextLayout : ConstraintLayout , PagedTextGenerateInterface {
|
||||
super.onLayout(changed, left, top, right, bottom)
|
||||
Blog.LOGD(log = "onLayout>> ${this::class.java.name} changed >> ${changed}")
|
||||
if(changed) {
|
||||
hiddenTextView?.text = text
|
||||
forceUpdateUI()
|
||||
// forceUpdateUI()
|
||||
}
|
||||
}
|
||||
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
|
||||
@ -470,14 +297,12 @@ class PagedTextLayout : ConstraintLayout , PagedTextGenerateInterface {
|
||||
|
||||
var currentPage = 0
|
||||
override fun completePagination(pageList: ArrayList<CharSequence>) {
|
||||
// Blog.LOGD(log = "completePagination>> ${this::class.java.name} >> pageList ${pageList}")
|
||||
if(text.length > 0 && pageList!= null && pageList.size == 0) {
|
||||
|
||||
} else {
|
||||
this.pageList = pageList
|
||||
setPageBy(0)
|
||||
}
|
||||
hiddenTextView?.visibility = GONE
|
||||
}
|
||||
var defaultAlpha = 171
|
||||
fun setColorStyle(colors : Array<String>) {
|
||||
@ -490,11 +315,7 @@ class PagedTextLayout : ConstraintLayout , PagedTextGenerateInterface {
|
||||
sencondTextView?.setTextColor(Color.parseColor("#FFFFFF"))
|
||||
}
|
||||
|
||||
// fun setPagedTextViewInterface(pagedTextViewInterface: PagedTextViewInterface) = hiddenTextView?.setPagedTextViewInterface(pagedTextViewInterface)
|
||||
// fun setText(replace: String) = hiddenTextView?.setText(replace)
|
||||
|
||||
fun setTextSize(fl: Float) {
|
||||
hiddenTextView?.setTextSize(fl)
|
||||
mainTextView?.setTextSize(fl)
|
||||
sencondTextView?.setTextSize(fl)
|
||||
}
|
||||
@ -508,22 +329,38 @@ class PagedTextLayout : ConstraintLayout , PagedTextGenerateInterface {
|
||||
}
|
||||
|
||||
fun setPageBy(num : Int) {
|
||||
if (pageList.size > 0) {
|
||||
this@PagedTextLayout.currentPage = num
|
||||
var realPage = if(isDualPage()) this@PagedTextLayout.currentPage * 2 else this@PagedTextLayout.currentPage
|
||||
Blog.LOGE("realPage = if(${pageList?.size} ?: 0 > ${realPage}) { realPage} else { ${(pageList?.size ?: 0) - 1 }}")
|
||||
realPage = if(pageList?.size ?: 0 > realPage) { realPage} else { (pageList?.size ?: 0) - 1 }
|
||||
currentPageTextView?.text = "${realPage + 1 }/${ pageList?.size ?: 0 + 1}"
|
||||
var realPage = if (isDualPage()) this@PagedTextLayout.currentPage * 2 else this@PagedTextLayout.currentPage
|
||||
Blog.LOGE("realPage = if(${pageList?.size} ?: 0 > ${realPage}) { realPage} else { ${(pageList?.size ?: 0) - 1}}")
|
||||
realPage = if (pageList?.size ?: 0 > realPage) {
|
||||
realPage
|
||||
} else {
|
||||
(pageList?.size ?: 0) - 1
|
||||
}
|
||||
currentPageTextView?.text = "${realPage + 1}/${pageList?.size ?: 0 + 1}"
|
||||
|
||||
mainTextView?.text = pageList?.get(realPage) ?: "NONE"
|
||||
if(isDualPage()) {
|
||||
Blog.LOGE("pageList.get($realPage) ${pageList?.get(realPage)}")
|
||||
if (isDualPage()) {
|
||||
realPage = realPage.inc()
|
||||
sencondTextView?.text = if(pageList?.size ?: 0 > realPage) { pageList?.get(realPage)} else { "끝"}
|
||||
sencondTextView?.text = if (pageList?.size ?: 0 > realPage) {
|
||||
pageList?.get(realPage)
|
||||
} else {
|
||||
"끝"
|
||||
}
|
||||
} else {
|
||||
sencondTextView?.text = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun size(): Int = (if(isDualPage()) {
|
||||
Math.round(pageList.size * 0.5f)
|
||||
}else {
|
||||
pageList.size
|
||||
})
|
||||
|
||||
fun size(): Int = if(isDualPage()) Math.round((hiddenTextView?.size() ?:0) * 0.5f) else hiddenTextView?.size() ?: 0
|
||||
fun getFastPageCount() = if(isDualPage()) 3 else 6
|
||||
fun current(): Int = this@PagedTextLayout.currentPage
|
||||
fun doNext(fast : Boolean = false) {
|
||||
@ -547,33 +384,26 @@ class PagedTextLayout : ConstraintLayout , PagedTextGenerateInterface {
|
||||
}
|
||||
}
|
||||
|
||||
fun forceUpdateUI() {
|
||||
hiddenTextView?.doUpdate()
|
||||
}
|
||||
|
||||
override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) {
|
||||
hiddenTextView?.setPadding(left,top,right, bottom)
|
||||
mainTextView?.setPadding(left,top,right, bottom)
|
||||
sencondTextView?.setPadding(left,top,right, bottom)
|
||||
}
|
||||
|
||||
|
||||
fun setTypeface(tf: Typeface?) {
|
||||
hiddenTextView?.setTypeface(tf)
|
||||
mainTextView?.setTypeface(tf)
|
||||
sencondTextView?.setTypeface(tf)
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
fun setLetterSpacing(letterSpacing: Float) {
|
||||
hiddenTextView?.letterSpacing = letterSpacing.times(0.01f)
|
||||
mainTextView?.letterSpacing = letterSpacing.times(0.01f)
|
||||
sencondTextView?.letterSpacing = letterSpacing.times(0.01f)
|
||||
}
|
||||
|
||||
|
||||
fun setLineSpacing(mult: Float) {
|
||||
hiddenTextView?.setLineSpacing(1f, 1f.plus(mult.times(0.01f)))
|
||||
mainTextView?.setLineSpacing(1f, 1f.plus(mult.times(0.01f)))
|
||||
sencondTextView?.setLineSpacing(1f, 1f.plus(mult.times(0.01f)))
|
||||
}
|
||||
|
||||
@ -6,32 +6,6 @@
|
||||
android:layout_margin="5dp"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_margin="5dp"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<bums.lunatic.launcher.home.tokiz.view.PagedTextView
|
||||
android:layout_margin="5dp"
|
||||
android:id="@+id/hidden_view"
|
||||
android:visibility="visible"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:includeFontPadding="false"
|
||||
android:lineSpacingExtra="0dp"
|
||||
style="@style/sss"
|
||||
android:layout_height="match_parent"/>
|
||||
<View
|
||||
android:id="@+id/demp"
|
||||
android:visibility="invisible"
|
||||
android:layout_margin="5dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_margin="5dp"
|
||||
android:layout_alignParentStart="true"
|
||||
@ -55,7 +29,7 @@
|
||||
android:gravity="start"
|
||||
android:includeFontPadding="false"
|
||||
android:lineSpacingExtra="0dp"
|
||||
android:visibility="invisible"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/sencond_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user