commit
ca7a000e4f
@ -1 +1 @@ |
||||
## 基类 |
||||
# 基类 |
@ -1 +1 @@ |
||||
## 放置一些帮助类 |
||||
# 放置一些帮助类 |
@ -1,4 +1,4 @@ |
||||
## 放置一些copy过来的库 |
||||
# 放置一些copy过来的库 |
||||
* dialogs 弹出框 |
||||
* theme 主题 |
||||
* webDav 网络存储 |
@ -1,4 +1,4 @@ |
||||
package io.legado.app.ui.book.chapterlist |
||||
package io.legado.app.ui.book.toc |
||||
|
||||
import android.view.LayoutInflater |
||||
import android.view.View |
@ -1,4 +1,4 @@ |
||||
package io.legado.app.ui.book.chapterlist |
||||
package io.legado.app.ui.book.toc |
||||
|
||||
import android.annotation.SuppressLint |
||||
import android.app.Activity |
@ -1,4 +1,4 @@ |
||||
package io.legado.app.ui.book.chapterlist |
||||
package io.legado.app.ui.book.toc |
||||
|
||||
import android.os.Bundle |
||||
import android.view.Menu |
@ -1,4 +1,4 @@ |
||||
package io.legado.app.ui.book.chapterlist |
||||
package io.legado.app.ui.book.toc |
||||
|
||||
import android.content.Context |
||||
import android.view.View |
@ -1,4 +1,4 @@ |
||||
package io.legado.app.ui.book.chapterlist |
||||
package io.legado.app.ui.book.toc |
||||
|
||||
import android.annotation.SuppressLint |
||||
import android.app.Activity.RESULT_OK |
@ -1,4 +1,4 @@ |
||||
package io.legado.app.ui.book.chapterlist |
||||
package io.legado.app.ui.book.toc |
||||
|
||||
|
||||
import android.app.Application |
@ -1,4 +1,4 @@ |
||||
package io.legado.app.ui.replacerule |
||||
package io.legado.app.ui.replace |
||||
|
||||
import android.os.Bundle |
||||
import androidx.recyclerview.widget.DiffUtil |
@ -1,4 +1,4 @@ |
||||
package io.legado.app.ui.replacerule |
||||
package io.legado.app.ui.replace |
||||
|
||||
import android.annotation.SuppressLint |
||||
import android.content.Context |
@ -1,4 +1,4 @@ |
||||
package io.legado.app.ui.replacerule |
||||
package io.legado.app.ui.replace |
||||
|
||||
import android.content.Context |
||||
import android.os.Bundle |
@ -1,4 +1,4 @@ |
||||
package io.legado.app.ui.replacerule |
||||
package io.legado.app.ui.replace |
||||
|
||||
import android.app.Application |
||||
import android.text.TextUtils |
@ -0,0 +1,166 @@ |
||||
package io.legado.app.ui.replace.edit |
||||
|
||||
import android.content.Context |
||||
import android.content.Intent |
||||
import android.graphics.Rect |
||||
import android.os.Bundle |
||||
import android.view.Gravity |
||||
import android.view.Menu |
||||
import android.view.MenuItem |
||||
import android.view.ViewTreeObserver |
||||
import android.widget.EditText |
||||
import android.widget.PopupWindow |
||||
import io.legado.app.R |
||||
import io.legado.app.base.VMBaseActivity |
||||
import io.legado.app.constant.AppConst |
||||
import io.legado.app.constant.EventBus |
||||
import io.legado.app.data.entities.ReplaceRule |
||||
import io.legado.app.ui.widget.KeyboardToolPop |
||||
import io.legado.app.utils.getViewModel |
||||
import io.legado.app.utils.postEvent |
||||
import kotlinx.android.synthetic.main.activity_replace_edit.* |
||||
import org.jetbrains.anko.displayMetrics |
||||
import org.jetbrains.anko.toast |
||||
import kotlin.math.abs |
||||
|
||||
/** |
||||
* 编辑替换规则 |
||||
*/ |
||||
class ReplaceEditActivity : |
||||
VMBaseActivity<ReplaceEditViewModel>(R.layout.activity_replace_edit, false), |
||||
ViewTreeObserver.OnGlobalLayoutListener, |
||||
KeyboardToolPop.CallBack { |
||||
|
||||
companion object { |
||||
|
||||
fun show( |
||||
context: Context, |
||||
id: Long = -1, |
||||
pattern: String? = null, |
||||
isRegex: Boolean = false, |
||||
scope: String? = null |
||||
) { |
||||
val intent = Intent(context, ReplaceEditActivity::class.java) |
||||
intent.putExtra("id", id) |
||||
intent.putExtra("pattern", pattern) |
||||
intent.putExtra("isRegex", isRegex) |
||||
intent.putExtra("scope", scope) |
||||
context.startActivity(intent) |
||||
} |
||||
} |
||||
|
||||
override val viewModel: ReplaceEditViewModel |
||||
get() = getViewModel(ReplaceEditViewModel::class.java) |
||||
|
||||
private var mSoftKeyboardTool: PopupWindow? = null |
||||
private var mIsSoftKeyBoardShowing = false |
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) { |
||||
mSoftKeyboardTool = KeyboardToolPop(this, AppConst.keyboardToolChars, this) |
||||
window.decorView.viewTreeObserver.addOnGlobalLayoutListener(this) |
||||
viewModel.replaceRuleData.observe(this, { |
||||
upReplaceView(it) |
||||
}) |
||||
viewModel.initData(intent) |
||||
} |
||||
|
||||
override fun onCompatCreateOptionsMenu(menu: Menu): Boolean { |
||||
menuInflater.inflate(R.menu.replace_edit, menu) |
||||
return super.onCompatCreateOptionsMenu(menu) |
||||
} |
||||
|
||||
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean { |
||||
when (item.itemId) { |
||||
R.id.menu_save -> { |
||||
val rule = getReplaceRule() |
||||
if (!rule.isValid()) { |
||||
toast(R.string.replace_rule_invalid) |
||||
} else { |
||||
viewModel.save(rule) { |
||||
postEvent(EventBus.REPLACE_RULE_SAVE, "") |
||||
finish() |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return true |
||||
} |
||||
|
||||
private fun upReplaceView(replaceRule: ReplaceRule) { |
||||
et_name.setText(replaceRule.name) |
||||
et_group.setText(replaceRule.group) |
||||
et_replace_rule.setText(replaceRule.pattern) |
||||
cb_use_regex.isChecked = replaceRule.isRegex |
||||
et_replace_to.setText(replaceRule.replacement) |
||||
et_scope.setText(replaceRule.scope) |
||||
} |
||||
|
||||
private fun getReplaceRule(): ReplaceRule { |
||||
val replaceRule: ReplaceRule = viewModel.replaceRuleData.value ?: ReplaceRule() |
||||
replaceRule.name = et_name.text.toString() |
||||
replaceRule.group = et_group.text.toString() |
||||
replaceRule.pattern = et_replace_rule.text.toString() |
||||
replaceRule.isRegex = cb_use_regex.isChecked |
||||
replaceRule.replacement = et_replace_to.text.toString() |
||||
replaceRule.scope = et_scope.text.toString() |
||||
return replaceRule |
||||
} |
||||
|
||||
private fun insertText(text: String) { |
||||
if (text.isBlank()) return |
||||
val view = window?.decorView?.findFocus() |
||||
if (view is EditText) { |
||||
val start = view.selectionStart |
||||
val end = view.selectionEnd |
||||
val edit = view.editableText//获取EditText的文字 |
||||
if (start < 0 || start >= edit.length) { |
||||
edit.append(text) |
||||
} else { |
||||
edit.replace(start, end, text)//光标所在位置插入文字 |
||||
} |
||||
} |
||||
} |
||||
|
||||
override fun sendText(text: String) { |
||||
if (text == AppConst.keyboardToolChars[0]) { |
||||
val view = window?.decorView?.findFocus() |
||||
view?.clearFocus() |
||||
} else { |
||||
insertText(text) |
||||
} |
||||
} |
||||
|
||||
private fun showKeyboardTopPopupWindow() { |
||||
mSoftKeyboardTool?.let { |
||||
if (it.isShowing) return |
||||
if (!isFinishing) { |
||||
it.showAtLocation(ll_content, Gravity.BOTTOM, 0, 0) |
||||
} |
||||
} |
||||
} |
||||
|
||||
private fun closePopupWindow() { |
||||
mSoftKeyboardTool?.dismiss() |
||||
} |
||||
|
||||
override fun onGlobalLayout() { |
||||
val rect = Rect() |
||||
// 获取当前页面窗口的显示范围 |
||||
window.decorView.getWindowVisibleDisplayFrame(rect) |
||||
val screenHeight = this.displayMetrics.heightPixels |
||||
val keyboardHeight = screenHeight - rect.bottom // 输入法的高度 |
||||
val preShowing = mIsSoftKeyBoardShowing |
||||
if (abs(keyboardHeight) > screenHeight / 5) { |
||||
mIsSoftKeyBoardShowing = true // 超过屏幕五分之一则表示弹出了输入法 |
||||
root_view.setPadding(0, 0, 0, 100) |
||||
showKeyboardTopPopupWindow() |
||||
} else { |
||||
mIsSoftKeyBoardShowing = false |
||||
root_view.setPadding(0, 0, 0, 0) |
||||
if (preShowing) { |
||||
closePopupWindow() |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
@ -1,156 +0,0 @@ |
||||
package io.legado.app.ui.replacerule.edit |
||||
|
||||
import android.os.Bundle |
||||
import android.view.LayoutInflater |
||||
import android.view.MenuItem |
||||
import android.view.View |
||||
import android.view.ViewGroup |
||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT |
||||
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT |
||||
import android.widget.EditText |
||||
import android.widget.PopupWindow |
||||
import androidx.appcompat.widget.Toolbar |
||||
import androidx.fragment.app.FragmentManager |
||||
import io.legado.app.R |
||||
import io.legado.app.base.BaseDialogFragment |
||||
import io.legado.app.constant.AppConst |
||||
import io.legado.app.data.entities.ReplaceRule |
||||
import io.legado.app.lib.theme.primaryColor |
||||
import io.legado.app.ui.widget.KeyboardToolPop |
||||
import io.legado.app.utils.applyTint |
||||
import io.legado.app.utils.getViewModel |
||||
import io.legado.app.utils.toast |
||||
import kotlinx.android.synthetic.main.dialog_replace_edit.* |
||||
import org.jetbrains.anko.sdk27.listeners.onFocusChange |
||||
|
||||
class ReplaceEditDialog : BaseDialogFragment(), |
||||
Toolbar.OnMenuItemClickListener, |
||||
KeyboardToolPop.CallBack { |
||||
|
||||
companion object { |
||||
|
||||
fun show( |
||||
fragmentManager: FragmentManager, |
||||
id: Long = -1, |
||||
pattern: String? = null, |
||||
isRegex: Boolean = false, |
||||
scope: String? = null |
||||
) { |
||||
val dialog = ReplaceEditDialog() |
||||
val bundle = Bundle() |
||||
bundle.putLong("id", id) |
||||
bundle.putString("pattern", pattern) |
||||
bundle.putBoolean("isRegex", isRegex) |
||||
bundle.putString("scope", scope) |
||||
dialog.arguments = bundle |
||||
dialog.show(fragmentManager, this::class.simpleName) |
||||
} |
||||
} |
||||
|
||||
private lateinit var viewModel: ReplaceEditViewModel |
||||
private lateinit var mSoftKeyboardTool: PopupWindow |
||||
|
||||
override fun onStart() { |
||||
super.onStart() |
||||
dialog?.window?.setLayout(MATCH_PARENT, WRAP_CONTENT) |
||||
} |
||||
|
||||
override fun onCreateView( |
||||
inflater: LayoutInflater, |
||||
container: ViewGroup?, |
||||
savedInstanceState: Bundle? |
||||
): View? { |
||||
viewModel = getViewModel(ReplaceEditViewModel::class.java) |
||||
return inflater.inflate(R.layout.dialog_replace_edit, container) |
||||
} |
||||
|
||||
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { |
||||
tool_bar.setBackgroundColor(primaryColor) |
||||
mSoftKeyboardTool = KeyboardToolPop(requireContext(), AppConst.keyboardToolChars, this) |
||||
tool_bar.inflateMenu(R.menu.replace_edit) |
||||
tool_bar.menu.applyTint(requireContext()) |
||||
tool_bar.setOnMenuItemClickListener(this) |
||||
viewModel.replaceRuleData.observe(viewLifecycleOwner, { |
||||
upReplaceView(it) |
||||
}) |
||||
arguments?.let { |
||||
viewModel.initData(it) |
||||
} |
||||
et_replace_rule.onFocusChange { v, hasFocus -> |
||||
if (hasFocus) { |
||||
mSoftKeyboardTool.width = v.width |
||||
mSoftKeyboardTool.showAsDropDown(v) |
||||
} else { |
||||
mSoftKeyboardTool.dismiss() |
||||
} |
||||
} |
||||
} |
||||
|
||||
override fun onMenuItemClick(item: MenuItem?): Boolean { |
||||
when (item?.itemId) { |
||||
R.id.menu_save -> { |
||||
val rule = getReplaceRule() |
||||
if (!rule.isValid()){ |
||||
toast(R.string.replace_rule_invalid) |
||||
} |
||||
else{ |
||||
viewModel.save(rule) { |
||||
callBack?.onReplaceRuleSave() |
||||
dismiss() |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return true |
||||
} |
||||
|
||||
private fun upReplaceView(replaceRule: ReplaceRule) { |
||||
et_name.setText(replaceRule.name) |
||||
et_group.setText(replaceRule.group) |
||||
et_replace_rule.setText(replaceRule.pattern) |
||||
cb_use_regex.isChecked = replaceRule.isRegex |
||||
et_replace_to.setText(replaceRule.replacement) |
||||
et_scope.setText(replaceRule.scope) |
||||
} |
||||
|
||||
private fun getReplaceRule(): ReplaceRule { |
||||
val replaceRule: ReplaceRule = viewModel.replaceRuleData.value ?: ReplaceRule() |
||||
replaceRule.name = et_name.text.toString() |
||||
replaceRule.group = et_group.text.toString() |
||||
replaceRule.pattern = et_replace_rule.text.toString() |
||||
replaceRule.isRegex = cb_use_regex.isChecked |
||||
replaceRule.replacement = et_replace_to.text.toString() |
||||
replaceRule.scope = et_scope.text.toString() |
||||
return replaceRule |
||||
} |
||||
|
||||
val callBack get() = activity as? CallBack |
||||
|
||||
private fun insertText(text: String) { |
||||
if (text.isBlank()) return |
||||
val view = dialog?.window?.decorView?.findFocus() |
||||
if (view is EditText) { |
||||
val start = view.selectionStart |
||||
val end = view.selectionEnd |
||||
val edit = view.editableText//获取EditText的文字 |
||||
if (start < 0 || start >= edit.length) { |
||||
edit.append(text) |
||||
} else { |
||||
edit.replace(start, end, text)//光标所在位置插入文字 |
||||
} |
||||
} |
||||
} |
||||
|
||||
override fun sendText(text: String) { |
||||
if (text == AppConst.keyboardToolChars[0]) { |
||||
val view = dialog?.window?.decorView?.findFocus() |
||||
view?.clearFocus() |
||||
} else { |
||||
insertText(text) |
||||
} |
||||
} |
||||
|
||||
interface CallBack { |
||||
fun onReplaceRuleSave() |
||||
} |
||||
} |
@ -1,19 +1,20 @@ |
||||
<?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:orientation="vertical" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent"> |
||||
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:orientation="vertical"> |
||||
|
||||
<io.legado.app.ui.widget.TitleBar |
||||
android:id="@+id/title_bar" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
app:contentLayout="@layout/view_tab_layout"/> |
||||
android:id="@+id/title_bar" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
app:contentInsetStartWithNavigation="0dp" |
||||
app:contentLayout="@layout/view_tab_layout" /> |
||||
|
||||
<androidx.viewpager.widget.ViewPager |
||||
android:id="@+id/view_pager" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent"/> |
||||
android:id="@+id/view_pager" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" /> |
||||
|
||||
</LinearLayout> |
@ -1,23 +1,23 @@ |
||||
<?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:orientation="vertical" |
||||
android:id="@+id/root_view" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent"> |
||||
android:layout_height="match_parent" |
||||
android:orientation="vertical"> |
||||
|
||||
<androidx.appcompat.widget.Toolbar |
||||
android:id="@+id/tool_bar" |
||||
android:background="@color/background_menu" |
||||
<io.legado.app.ui.widget.TitleBar |
||||
android:id="@+id/title_bar" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:theme="?attr/actionBarStyle" |
||||
app:titleTextAppearance="@style/ToolbarTitle" |
||||
app:popupTheme="@style/AppTheme.PopupOverlay" |
||||
app:contentInsetStartWithNavigation="0dp" |
||||
app:displayHomeAsUp="true" |
||||
app:fitStatusBar="false" |
||||
app:title="@string/replace_rule_edit" /> |
||||
|
||||
<ScrollView |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent"> |
||||
android:layout_height="wrap_content"> |
||||
|
||||
<LinearLayout |
||||
android:id="@+id/ll_content" |
@ -1,12 +1,31 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:id="@+id/refresh_layout" |
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent"> |
||||
android:layout_height="match_parent" |
||||
xmlns:tools="http://schemas.android.com/tools"> |
||||
|
||||
<androidx.recyclerview.widget.RecyclerView |
||||
android:id="@+id/rv_bookshelf" |
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout |
||||
android:id="@+id/refresh_layout" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" /> |
||||
android:layout_height="match_parent"> |
||||
|
||||
<androidx.recyclerview.widget.RecyclerView |
||||
android:id="@+id/rv_bookshelf" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
tools:listitem="@layout/item_bookshelf_list" /> |
||||
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> |
||||
|
||||
<TextView |
||||
android:id="@+id/tv_empty_msg" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_margin="16dp" |
||||
android:gravity="center" |
||||
android:layout_gravity="center" |
||||
android:visibility="gone" |
||||
tools:text="TextView" /> |
||||
|
||||
</FrameLayout> |
||||
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> |
@ -1,20 +1,40 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||
android:orientation="vertical" |
||||
xmlns:tools="http://schemas.android.com/tools" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent"> |
||||
android:layout_height="match_parent" |
||||
android:orientation="vertical"> |
||||
|
||||
<io.legado.app.ui.widget.TitleBar |
||||
android:id="@+id/title_bar" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
app:attachToActivity="false" |
||||
app:layout_constraintTop_toTopOf="parent" |
||||
app:title="@string/rss" /> |
||||
|
||||
<androidx.recyclerview.widget.RecyclerView |
||||
android:id="@+id/recycler_view" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" /> |
||||
android:layout_height="0dp" |
||||
app:layout_constraintTop_toBottomOf="@id/title_bar" |
||||
app:layout_constraintBottom_toBottomOf="parent" |
||||
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager" |
||||
app:spanCount="4" |
||||
tools:listitem="@layout/item_rss" /> |
||||
|
||||
</LinearLayout> |
||||
<TextView |
||||
android:id="@+id/tv_empty_msg" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_margin="16dp" |
||||
android:gravity="center" |
||||
android:visibility="gone" |
||||
app:layout_constraintTop_toBottomOf="@+id/title_bar" |
||||
app:layout_constraintBottom_toBottomOf="parent" |
||||
app:layout_constraintLeft_toLeftOf="parent" |
||||
app:layout_constraintRight_toRightOf="parent" |
||||
tools:text="TextView" /> |
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout> |
@ -1,8 +0,0 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="60dp" |
||||
android:background="?android:attr/selectableItemBackground" |
||||
android:gravity="center" |
||||
android:text="@string/add" |
||||
android:textSize="24sp" /> |
@ -1,6 +1,6 @@ |
||||
#Sat May 30 10:00:31 CST 2020 |
||||
#Tue Oct 13 11:35:54 CST 2020 |
||||
distributionBase=GRADLE_USER_HOME |
||||
distributionPath=wrapper/dists |
||||
zipStoreBase=GRADLE_USER_HOME |
||||
zipStorePath=wrapper/dists |
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip |
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip |
||||
|
Loading…
Reference in new issue