优化:MainActivity 内容填充方式(避免一次性加载多个Fragment)&& 提升APP启动速度与稳定性

优化:左滑菜单 与 TabBar 美化
精简:界面调整 & 去除不常用资源
整理:code review
This commit is contained in:
pppscn 2023-12-19 23:52:50 +08:00
parent 70d685ee93
commit 6473b3eb7c
200 changed files with 2130 additions and 1764 deletions

View File

@ -306,6 +306,11 @@ dependencies {
implementation 'gatewayapps.crondroid:crondroid:1.0.0' implementation 'gatewayapps.crondroid:crondroid:1.0.0'
//Java Parser For Cron Expressions: https://github.com/grahamar/cron-parser //Java Parser For Cron Expressions: https://github.com/grahamar/cron-parser
implementation 'net.redhogs.cronparser:cron-parser-core:3.5' implementation 'net.redhogs.cronparser:cron-parser-core:3.5'
// https://github.com/yarolegovich/SlidingRootNav
implementation 'com.yarolegovich:sliding-root-nav:1.1.1'
// TabBarhttps://github.com/xuexiangjys/JPTabBar
// implementation 'com.github.xuexiangjys:JPTabBar:1.0.1'
} }
//X-Library依赖 //X-Library依赖
apply from: 'x-library.gradle' apply from: 'x-library.gradle'

View File

@ -298,3 +298,7 @@
-dontwarn javax.lang.model.** -dontwarn javax.lang.model.**
-dontwarn javax.naming.** -dontwarn javax.naming.**
-dontwarn javax.naming.directory.** -dontwarn javax.naming.directory.**
# This is generated automatically by the Android Gradle plugin.
-dontwarn org.joda.convert.**
-dontwarn org.slf4j.impl.**

View File

@ -16,6 +16,7 @@
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<!-- 授予应用程序访问系统开机事件的权限 --> <!-- 授予应用程序访问系统开机事件的权限 -->
<uses-permission <uses-permission
@ -67,12 +68,6 @@
<uses-permission <uses-permission
android:name="android.permission.REBOOT" android:name="android.permission.REBOOT"
tools:ignore="ProtectedPermissions" /> tools:ignore="ProtectedPermissions" />
<uses-permission
android:name="android.permission.WRITE_SETTINGS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<application <application
android:name=".App" android:name=".App"

View File

@ -74,8 +74,7 @@ class App : Application(), CactusCallback, Configuration.Provider by Core {
/** /**
* @return 当前app是否是调试开发模式 * @return 当前app是否是调试开发模式
*/ */
val isDebug: Boolean val isDebug: Boolean = BuildConfig.DEBUG
get() = BuildConfig.DEBUG
//Cactus相关 //Cactus相关
val mEndDate = MutableLiveData<String>() //结束时间 val mEndDate = MutableLiveData<String>() //结束时间

View File

@ -1,77 +1,94 @@
package com.idormy.sms.forwarder.activity package com.idormy.sms.forwarder.activity
import android.annotation.SuppressLint
import android.app.ActivityManager import android.app.ActivityManager
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.drawable.Drawable
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.MenuItem import android.widget.LinearLayout
import android.view.View import androidx.recyclerview.widget.LinearLayoutManager
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.widget.Toolbar
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager.widget.ViewPager
import androidx.work.OneTimeWorkRequestBuilder import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager import androidx.work.WorkManager
import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.tabs.TabLayout
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.hjq.permissions.OnPermissionCallback import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.Permission import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions import com.hjq.permissions.XXPermissions
import com.idormy.sms.forwarder.App import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.adapter.WidgetItemAdapter import com.idormy.sms.forwarder.adapter.menu.DrawerAdapter
import com.idormy.sms.forwarder.adapter.menu.DrawerItem
import com.idormy.sms.forwarder.adapter.menu.SimpleItem
import com.idormy.sms.forwarder.adapter.menu.SpaceItem
import com.idormy.sms.forwarder.core.BaseActivity import com.idormy.sms.forwarder.core.BaseActivity
import com.idormy.sms.forwarder.core.webview.AgentWebActivity import com.idormy.sms.forwarder.core.webview.AgentWebActivity
import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.databinding.ActivityMainBinding import com.idormy.sms.forwarder.databinding.ActivityMainBinding
import com.idormy.sms.forwarder.fragment.* import com.idormy.sms.forwarder.fragment.AboutFragment
import com.idormy.sms.forwarder.fragment.AppListFragment
import com.idormy.sms.forwarder.fragment.ClientFragment
import com.idormy.sms.forwarder.fragment.FrpcFragment
import com.idormy.sms.forwarder.fragment.LogsFragment
import com.idormy.sms.forwarder.fragment.RulesFragment
import com.idormy.sms.forwarder.fragment.SendersFragment
import com.idormy.sms.forwarder.fragment.ServerFragment
import com.idormy.sms.forwarder.fragment.SettingsFragment
import com.idormy.sms.forwarder.fragment.TasksFragment
import com.idormy.sms.forwarder.service.ForegroundService import com.idormy.sms.forwarder.service.ForegroundService
import com.idormy.sms.forwarder.utils.* import com.idormy.sms.forwarder.utils.FRPC_LIB_DOWNLOAD_URL
import com.idormy.sms.forwarder.utils.FRPC_LIB_VERSION
import com.idormy.sms.forwarder.utils.SettingUtils
import com.idormy.sms.forwarder.utils.XToastUtils
import com.idormy.sms.forwarder.utils.sdkinit.XUpdateInit import com.idormy.sms.forwarder.utils.sdkinit.XUpdateInit
import com.idormy.sms.forwarder.widget.GuideTipsDialog.Companion.showTips import com.idormy.sms.forwarder.widget.GuideTipsDialog.Companion.showTips
import com.idormy.sms.forwarder.widget.GuideTipsDialog.Companion.showTipsForce
import com.idormy.sms.forwarder.workers.LoadAppListWorker import com.idormy.sms.forwarder.workers.LoadAppListWorker
import com.jeremyliao.liveeventbus.LiveEventBus
import com.xuexiang.xaop.annotation.SingleClick
import com.xuexiang.xhttp2.XHttp import com.xuexiang.xhttp2.XHttp
import com.xuexiang.xhttp2.callback.DownloadProgressCallBack import com.xuexiang.xhttp2.callback.DownloadProgressCallBack
import com.xuexiang.xhttp2.exception.ApiException import com.xuexiang.xhttp2.exception.ApiException
import com.xuexiang.xpage.base.XPageFragment
import com.xuexiang.xpage.core.PageOption
import com.xuexiang.xpage.model.PageInfo
import com.xuexiang.xui.adapter.FragmentAdapter
import com.xuexiang.xui.adapter.recyclerview.RecyclerViewHolder
import com.xuexiang.xui.utils.DensityUtils
import com.xuexiang.xui.utils.ResUtils import com.xuexiang.xui.utils.ResUtils
import com.xuexiang.xui.utils.ThemeUtils
import com.xuexiang.xui.utils.ViewUtils
import com.xuexiang.xui.utils.WidgetUtils import com.xuexiang.xui.utils.WidgetUtils
import com.xuexiang.xui.widget.alpha.XUIAlphaTextView
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
import com.xuexiang.xui.widget.dialog.materialdialog.GravityEnum import com.xuexiang.xui.widget.dialog.materialdialog.GravityEnum
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
import com.xuexiang.xutil.file.FileUtils import com.xuexiang.xutil.file.FileUtils
import com.xuexiang.xutil.net.NetworkUtils import com.xuexiang.xutil.net.NetworkUtils
import com.yarolegovich.slidingrootnav.SlideGravity
import com.yarolegovich.slidingrootnav.SlidingRootNav
import com.yarolegovich.slidingrootnav.SlidingRootNavBuilder
import com.yarolegovich.slidingrootnav.callback.DragStateListener
import frpclib.Frpclib import frpclib.Frpclib
import io.reactivex.CompletableObserver
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import java.io.File import java.io.File
@Suppress("DEPRECATION", "PrivatePropertyName") @Suppress("PrivatePropertyName", "unused", "DEPRECATION")
class MainActivity : BaseActivity<ActivityMainBinding?>(), class MainActivity : BaseActivity<ActivityMainBinding?>(), DrawerAdapter.OnItemSelectedListener {
View.OnClickListener,
BottomNavigationView.OnNavigationItemSelectedListener,
Toolbar.OnMenuItemClickListener,
RecyclerViewHolder.OnItemClickListener<PageInfo> {
private val TAG: String = MainActivity::class.java.simpleName private val TAG: String = MainActivity::class.java.simpleName
private lateinit var mTitles: Array<String> //private lateinit var mTitles: Array<String>
private var logsType: String = "sms" //private var logsType: String = "sms"
private var ruleType: String = "sms" //private var ruleType: String = "sms"
private val POS_LOG = 0
private val POS_RULE = 1
private val POS_SENDER = 2
private val POS_SETTING = 3
private val POS_TASK = 5 //4为空行
private val POS_SERVER = 6
private val POS_CLIENT = 7
private val POS_FRPC = 8
private val POS_APPS = 9
private val POS_HELP = 11 //10为空行
private val POS_ABOUT = 12
private lateinit var mTabLayout: TabLayout
private lateinit var mSlidingRootNav: SlidingRootNav
private lateinit var mLLMenu: LinearLayout
private lateinit var mMenuTitles: Array<String>
private lateinit var mMenuIcons: Array<Drawable>
private lateinit var mAdapter: DrawerAdapter
override fun viewBindingInflate(inflater: LayoutInflater?): ActivityMainBinding { override fun viewBindingInflate(inflater: LayoutInflater?): ActivityMainBinding {
return ActivityMainBinding.inflate(inflater!!) return ActivityMainBinding.inflate(inflater!!)
@ -79,9 +96,10 @@ class MainActivity : BaseActivity<ActivityMainBinding?>(),
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
initViews()
initData() initData()
initListeners() initViews()
initSlidingMenu(savedInstanceState)
//不在最近任务列表中显示 //不在最近任务列表中显示
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && SettingUtils.enableExcludeFromRecents) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && SettingUtils.enableExcludeFromRecents) {
@ -95,26 +113,23 @@ class MainActivity : BaseActivity<ActivityMainBinding?>(),
} }
//检查通知权限是否获取 //检查通知权限是否获取
XXPermissions.with(this) XXPermissions.with(this).permission(Permission.NOTIFICATION_SERVICE).permission(Permission.POST_NOTIFICATIONS).request(OnPermissionCallback { _, allGranted ->
.permission(Permission.NOTIFICATION_SERVICE) if (!allGranted) {
.permission(Permission.POST_NOTIFICATIONS) XToastUtils.error(R.string.tips_notification)
.request(OnPermissionCallback { _, allGranted -> return@OnPermissionCallback
if (!allGranted) { }
XToastUtils.error(R.string.tips_notification)
return@OnPermissionCallback
}
//启动前台服务 //启动前台服务
if (!ForegroundService.isRunning) { if (!ForegroundService.isRunning) {
val serviceIntent = Intent(this, ForegroundService::class.java) val serviceIntent = Intent(this, ForegroundService::class.java)
serviceIntent.action = "START" serviceIntent.action = "START"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(serviceIntent) startForegroundService(serviceIntent)
} else { } else {
startService(serviceIntent) startService(serviceIntent)
}
} }
}) }
})
} }
override val isSupportSlideBack: Boolean override val isSupportSlideBack: Boolean
@ -122,24 +137,37 @@ class MainActivity : BaseActivity<ActivityMainBinding?>(),
private fun initViews() { private fun initViews() {
WidgetUtils.clearActivityBackground(this) WidgetUtils.clearActivityBackground(this)
mTitles = ResUtils.getStringArray(R.array.home_titles) initTab()
binding!!.includeMain.toolbar.title = mTitles[0] }
binding!!.includeMain.toolbar.inflateMenu(R.menu.menu_logs)
binding!!.includeMain.toolbar.setOnMenuItemClickListener(this)
//主页内容填充 private fun initTab() {
val fragments = arrayOf( mTabLayout = binding!!.tabs
LogsFragment(), WidgetUtils.addTabWithoutRipple(mTabLayout, getString(R.string.menu_logs), R.drawable.selector_icon_tabbar_logs)
RulesFragment(), WidgetUtils.addTabWithoutRipple(mTabLayout, getString(R.string.menu_rules), R.drawable.selector_icon_tabbar_rules)
SendersFragment(), WidgetUtils.addTabWithoutRipple(mTabLayout, getString(R.string.menu_senders), R.drawable.selector_icon_tabbar_senders)
SettingsFragment() WidgetUtils.addTabWithoutRipple(mTabLayout, getString(R.string.menu_settings), R.drawable.selector_icon_tabbar_settings)
) WidgetUtils.setTabLayoutTextFont(mTabLayout)
val adapter = FragmentAdapter(supportFragmentManager, fragments) switchPage(LogsFragment::class.java)
binding!!.includeMain.viewPager.offscreenPageLimit = mTitles.size - 1 mTabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
binding!!.includeMain.viewPager.adapter = adapter override fun onTabSelected(tab: TabLayout.Tab) {
mAdapter.setSelected(tab.position)
when (tab.position) {
POS_LOG -> switchPage(LogsFragment::class.java)
POS_RULE -> switchPage(RulesFragment::class.java)
POS_SENDER -> switchPage(SendersFragment::class.java)
POS_SETTING -> switchPage(SettingsFragment::class.java)
}
}
override fun onTabUnselected(tab: TabLayout.Tab) {}
override fun onTabReselected(tab: TabLayout.Tab) {}
})
} }
private fun initData() { private fun initData() {
mMenuTitles = ResUtils.getStringArray(this, R.array.menu_titles)
mMenuIcons = ResUtils.getDrawableArray(this, R.array.menu_icons)
//仅当开启自动检查且有网络时自动检查更新/获取提示 //仅当开启自动检查且有网络时自动检查更新/获取提示
if (SettingUtils.autoCheckUpdate && NetworkUtils.isHaveInternet()) { if (SettingUtils.autoCheckUpdate && NetworkUtils.isHaveInternet()) {
showTips(this) showTips(this)
@ -147,243 +175,6 @@ class MainActivity : BaseActivity<ActivityMainBinding?>(),
} }
} }
fun initListeners() {
val toggle = ActionBarDrawerToggle(
this,
binding!!.drawerLayout,
binding!!.includeMain.toolbar,
R.string.navigation_drawer_open,
R.string.navigation_drawer_close
)
binding!!.drawerLayout.addDrawerListener(toggle)
toggle.syncState()
//侧边栏点击事件
binding!!.navView.setNavigationItemSelectedListener { menuItem: MenuItem ->
if (menuItem.isCheckable) {
binding!!.drawerLayout.closeDrawers()
return@setNavigationItemSelectedListener handleNavigationItemSelected(menuItem)
} else {
when (menuItem.itemId) {
R.id.nav_task -> openNewPage(TasksFragment::class.java)
R.id.nav_server -> openNewPage(ServerFragment::class.java)
R.id.nav_client -> openNewPage(ClientFragment::class.java)
R.id.nav_frpc -> {
if (!FileUtils.isFileExists(filesDir.absolutePath + "/libs/libgojni.so")) {
MaterialDialog.Builder(this)
.title(
String.format(
getString(R.string.frpclib_download_title),
FRPC_LIB_VERSION
)
)
.content(R.string.download_frpc_tips)
.positiveText(R.string.lab_yes)
.negativeText(R.string.lab_no)
.onPositive { _: MaterialDialog?, _: DialogAction? ->
downloadFrpcLib()
}
.show()
return@setNavigationItemSelectedListener false
}
if (FRPC_LIB_VERSION == Frpclib.getVersion()) {
openNewPage(FrpcFragment::class.java)
} else {
MaterialDialog.Builder(this)
.title(R.string.frpclib_version_mismatch)
.content(R.string.download_frpc_tips)
.positiveText(R.string.lab_yes)
.negativeText(R.string.lab_no)
.onPositive { _: MaterialDialog?, _: DialogAction? ->
downloadFrpcLib()
}
.show()
}
}
R.id.nav_app_list -> {
if (App.UserAppList.isEmpty() && App.SystemAppList.isEmpty()) {
XToastUtils.info(getString(R.string.loading_app_list))
val request = OneTimeWorkRequestBuilder<LoadAppListWorker>().build()
WorkManager.getInstance(this).enqueue(request)
Thread.sleep(2000)
}
openNewPage(AppListFragment::class.java)
}
//R.id.nav_logcat -> openNewPage(LogcatFragment::class.java)
R.id.nav_help -> AgentWebActivity.goWeb(this, getString(R.string.url_help))
R.id.nav_about -> openNewPage(AboutFragment::class.java)
else -> XToastUtils.toast("Click:" + menuItem.title)
}
}
true
}
//主页事件监听
binding!!.includeMain.viewPager.addOnPageChangeListener(object :
ViewPager.OnPageChangeListener {
override fun onPageScrolled(
position: Int,
positionOffset: Float,
positionOffsetPixels: Int,
) {
}
override fun onPageSelected(position: Int) {
val item = binding!!.includeMain.bottomNavigation.menu.getItem(position)
binding!!.includeMain.toolbar.title = item.title
binding!!.includeMain.toolbar.menu.clear()
when (item.title) {
getString(R.string.menu_rules) -> binding!!.includeMain.toolbar.inflateMenu(
R.menu.menu_rules
)
getString(R.string.menu_senders) -> binding!!.includeMain.toolbar.inflateMenu(
R.menu.menu_senders
)
getString(R.string.menu_settings) -> binding!!.includeMain.toolbar.inflateMenu(
R.menu.menu_settings
)
else -> binding!!.includeMain.toolbar.inflateMenu(R.menu.menu_logs)
}
item.isChecked = true
updateSideNavStatus(item)
}
override fun onPageScrollStateChanged(state: Int) {}
})
binding!!.includeMain.bottomNavigation.setOnNavigationItemSelectedListener(this)
//tabBar分类切换
LiveEventBus.get(EVENT_UPDATE_LOGS_TYPE, String::class.java).observe(this) { type: String ->
logsType = type
}
LiveEventBus.get(EVENT_UPDATE_RULE_TYPE, String::class.java).observe(this) { type: String ->
ruleType = type
}
}
/**
* 处理侧边栏点击事件
*
* @param menuItem
* @return
*/
private fun handleNavigationItemSelected(menuItem: MenuItem): Boolean {
for (index in mTitles.indices) {
if (mTitles[index] == menuItem.title) {
binding!!.includeMain.toolbar.title = menuItem.title
binding!!.includeMain.viewPager.setCurrentItem(index, false)
return true
}
}
return false
}
@SuppressLint("InflateParams")
override fun onMenuItemClick(item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_notifications -> {
showTipsForce(this)
}
R.id.action_clear_logs -> {
MaterialDialog.Builder(this)
.content(R.string.delete_type_log_tips)
.positiveText(R.string.lab_yes)
.negativeText(R.string.lab_no)
.onPositive { _: MaterialDialog?, _: DialogAction? ->
AppDatabase.getInstance(this)
.msgDao()
.deleteAll(logsType)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : CompletableObserver {
override fun onSubscribe(d: Disposable) {}
override fun onComplete() {
XToastUtils.success(R.string.delete_type_log_toast)
}
override fun onError(e: Throwable) {
e.message?.let { XToastUtils.error(it) }
}
})
}
.show()
}
R.id.action_add_sender -> {
val dialog = BottomSheetDialog(this)
val view: View =
LayoutInflater.from(this).inflate(R.layout.dialog_sender_bottom_sheet, null)
val recyclerView: RecyclerView = view.findViewById(R.id.recyclerView)
WidgetUtils.initGridRecyclerView(recyclerView, 4, DensityUtils.dp2px(1f))
val widgetItemAdapter = WidgetItemAdapter(SENDER_FRAGMENT_LIST)
widgetItemAdapter.setOnItemClickListener(this)
recyclerView.adapter = widgetItemAdapter
val bottomSheetCloseButton: XUIAlphaTextView = view.findViewById(R.id.bottom_sheet_close_button)
bottomSheetCloseButton.setOnClickListener { dialog.dismiss() }
dialog.setContentView(view)
dialog.setCancelable(true)
dialog.setCanceledOnTouchOutside(true)
dialog.show()
WidgetUtils.transparentBottomSheetDialogBackground(dialog)
}
R.id.action_add_rule -> {
PageOption.to(RulesEditFragment::class.java)
.putString(KEY_RULE_TYPE, ruleType)
.setNewActivity(true)
.open(this)
}
/*R.id.action_restore_settings -> {
XToastUtils.success(logsType)
}*/
}
return false
}
@SingleClick
override fun onClick(v: View) {
}
//================Navigation================//
/**
* 底部导航栏点击事件
*
* @param menuItem
* @return
*/
override fun onNavigationItemSelected(menuItem: MenuItem): Boolean {
for (index in mTitles.indices) {
if (mTitles[index] == menuItem.title) {
binding!!.includeMain.toolbar.title = menuItem.title
binding!!.includeMain.viewPager.setCurrentItem(index, false)
updateSideNavStatus(menuItem)
return true
}
}
return false
}
/**
* 更新侧边栏菜单选中状态
*
* @param menuItem
*/
private fun updateSideNavStatus(menuItem: MenuItem) {
val side = binding!!.navView.menu.findItem(menuItem.itemId)
if (side != null) {
side.isChecked = true
}
}
//按返回键不退出回到桌面 //按返回键不退出回到桌面
@Deprecated("Deprecated in Java") @Deprecated("Deprecated in Java")
override fun onBackPressed() { override fun onBackPressed() {
@ -393,20 +184,137 @@ class MainActivity : BaseActivity<ActivityMainBinding?>(),
startActivity(intent) startActivity(intent)
} }
@SingleClick fun openMenu() {
override fun onItemClick(itemView: View, widgetInfo: PageInfo, pos: Int) { mSlidingRootNav.openMenu()
try { }
@Suppress("UNCHECKED_CAST")
PageOption.to(Class.forName(widgetInfo.classPath) as Class<XPageFragment>) //跳转的fragment fun closeMenu() {
.setNewActivity(true) mSlidingRootNav.closeMenu()
.putInt(KEY_SENDER_TYPE, pos) //注意:目前刚好是这个顺序而已 }
.open(this)
} catch (e: Exception) { fun isMenuOpen(): Boolean {
e.printStackTrace() return mSlidingRootNav.isMenuOpened
XToastUtils.error(e.message.toString()) }
private fun initSlidingMenu(savedInstanceState: Bundle?) {
mSlidingRootNav = SlidingRootNavBuilder(this).withGravity(if (ResUtils.isRtl(this)) SlideGravity.RIGHT else SlideGravity.LEFT).withMenuOpened(false).withContentClickableWhenMenuOpened(false).withSavedState(savedInstanceState).withMenuLayout(R.layout.menu_left_drawer).inject()
mLLMenu = mSlidingRootNav.layout.findViewById(R.id.ll_menu)
//val ivQrcode = mSlidingRootNav.layout.findViewById<AppCompatImageView>(R.id.iv_qrcode)
//ivQrcode.setOnClickListener { openNewPage(SettingsFragment::class.java) }
//val ivSetting = mSlidingRootNav.layout.findViewById<AppCompatImageView>(R.id.iv_setting)
//ivSetting.setOnClickListener { openNewPage(SettingsFragment::class.java) }
ViewUtils.setVisibility(mLLMenu, false)
mAdapter = DrawerAdapter(
mutableListOf(
createItemFor(POS_LOG).setChecked(true),
createItemFor(POS_RULE),
createItemFor(POS_SENDER),
createItemFor(POS_SETTING),
SpaceItem(15),
createItemFor(POS_TASK),
createItemFor(POS_SERVER),
createItemFor(POS_CLIENT),
createItemFor(POS_FRPC),
createItemFor(POS_APPS),
SpaceItem(15),
createItemFor(POS_HELP),
createItemFor(POS_ABOUT),
)
)
mAdapter.setListener(this)
val list: RecyclerView = findViewById(R.id.list)
list.isNestedScrollingEnabled = false
list.layoutManager = LinearLayoutManager(this)
list.adapter = mAdapter
mAdapter.setSelected(POS_LOG)
mSlidingRootNav.isMenuLocked = false
mSlidingRootNav.layout.addDragStateListener(object : DragStateListener {
override fun onDragStart() {
ViewUtils.setVisibility(mLLMenu, true)
}
override fun onDragEnd(isMenuOpened: Boolean) {
ViewUtils.setVisibility(mLLMenu, isMenuOpened)
/*if (isMenuOpened) {
if (!GuideCaseView.isShowOnce(this@MainActivity, getString(R.string.guide_key_sliding_root_navigation))) {
val guideStep1 = GuideCaseView.Builder(this@MainActivity)
.title("点击进入,可切换主题样式哦~~")
.titleSize(18, TypedValue.COMPLEX_UNIT_SP)
.focusOn(ivSetting)
.build()
val guideStep2 = GuideCaseView.Builder(this@MainActivity)
.title("点击进入,扫码关注哦~~")
.titleSize(18, TypedValue.COMPLEX_UNIT_SP)
.focusOn(ivQrcode)
.build()
GuideCaseQueue()
.add(guideStep1)
.add(guideStep2)
.show()
GuideCaseView.setShowOnce(this@MainActivity, getString(R.string.guide_key_sliding_root_navigation))
}
}*/
}
})
}
override fun onItemSelected(position: Int) {
when (position) {
POS_LOG, POS_RULE, POS_SENDER, POS_SETTING -> {
val tab = mTabLayout.getTabAt(position)
tab?.select()
mSlidingRootNav.closeMenu()
}
POS_TASK -> openNewPage(TasksFragment::class.java)
POS_SERVER -> openNewPage(ServerFragment::class.java)
POS_CLIENT -> openNewPage(ClientFragment::class.java)
POS_FRPC -> {
if (FileUtils.isFileExists(filesDir.absolutePath + "/libs/libgojni.so") && FRPC_LIB_VERSION == Frpclib.getVersion()) {
openNewPage(FrpcFragment::class.java)
return
}
val title = if (!FileUtils.isFileExists(filesDir.absolutePath + "/libs/libgojni.so")) {
String.format(getString(R.string.frpclib_download_title), FRPC_LIB_VERSION)
} else {
getString(R.string.frpclib_version_mismatch)
}
MaterialDialog.Builder(this)
.title(title)
.content(R.string.download_frpc_tips)
.positiveText(R.string.lab_yes)
.negativeText(R.string.lab_no)
.onPositive { _: MaterialDialog?, _: DialogAction? ->
downloadFrpcLib()
}
.show()
}
POS_APPS -> {
if (App.UserAppList.isEmpty() && App.SystemAppList.isEmpty()) {
XToastUtils.info(getString(R.string.loading_app_list))
val request = OneTimeWorkRequestBuilder<LoadAppListWorker>().build()
WorkManager.getInstance(this).enqueue(request)
return
}
openNewPage(AppListFragment::class.java)
}
POS_HELP -> AgentWebActivity.goWeb(this, getString(R.string.url_help))
POS_ABOUT -> openNewPage(AboutFragment::class.java)
} }
} }
private fun createItemFor(position: Int): DrawerItem<*> {
return SimpleItem(mMenuIcons[position], mMenuTitles[position])
.withIconTint(ThemeUtils.resolveColor(this, R.attr.xui_config_color_content_text))
.withTextTint(ThemeUtils.resolveColor(this, R.attr.xui_config_color_content_text))
.withSelectedIconTint(ThemeUtils.getMainThemeColor(this))
.withSelectedTextTint(ThemeUtils.getMainThemeColor(this))
}
//动态加载FrpcLib //动态加载FrpcLib
private fun downloadFrpcLib() { private fun downloadFrpcLib() {
val cpuAbi = when (Build.CPU_ABI) { val cpuAbi = when (Build.CPU_ABI) {

View File

@ -15,6 +15,7 @@ import com.idormy.sms.forwarder.databinding.AdapterFrpcsCardViewListItemBinding
import com.xuexiang.xutil.resource.ResUtils.getColors import com.xuexiang.xutil.resource.ResUtils.getColors
import frpclib.Frpclib import frpclib.Frpclib
@Suppress("EmptyMethod", "unused")
class FrpcPagingAdapter(private val itemClickListener: OnItemClickListener) : PagingDataAdapter<Frpc, MyViewHolder>(diffCallback) { class FrpcPagingAdapter(private val itemClickListener: OnItemClickListener) : PagingDataAdapter<Frpc, MyViewHolder>(diffCallback) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {

View File

@ -12,7 +12,6 @@ import com.idormy.sms.forwarder.database.entity.LogsAndRuleAndSender
import com.idormy.sms.forwarder.databinding.AdapterLogsCardViewListItemBinding import com.idormy.sms.forwarder.databinding.AdapterLogsCardViewListItemBinding
import com.xuexiang.xutil.data.DateUtils import com.xuexiang.xutil.data.DateUtils
@Suppress("unused")
class LogsPagingAdapter(private val itemClickListener: OnItemClickListener) : PagingDataAdapter<LogsAndRuleAndSender, MyViewHolder>(diffCallback) { class LogsPagingAdapter(private val itemClickListener: OnItemClickListener) : PagingDataAdapter<LogsAndRuleAndSender, MyViewHolder>(diffCallback) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {

View File

@ -18,6 +18,7 @@ import com.idormy.sms.forwarder.database.entity.MsgAndLogs
import com.idormy.sms.forwarder.databinding.AdapterLogsCardViewListItemBinding import com.idormy.sms.forwarder.databinding.AdapterLogsCardViewListItemBinding
import com.xuexiang.xutil.data.DateUtils import com.xuexiang.xutil.data.DateUtils
@Suppress("EmptyMethod", "unused")
class MsgPagingAdapter(private val itemClickListener: OnItemClickListener) : PagingDataAdapter<MsgAndLogs, MyViewHolder>(diffCallback) { class MsgPagingAdapter(private val itemClickListener: OnItemClickListener) : PagingDataAdapter<MsgAndLogs, MyViewHolder>(diffCallback) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {

View File

@ -16,6 +16,7 @@ import com.idormy.sms.forwarder.adapter.RulePagingAdapter.MyViewHolder
import com.idormy.sms.forwarder.database.entity.Rule import com.idormy.sms.forwarder.database.entity.Rule
import com.idormy.sms.forwarder.databinding.AdapterRulesCardViewListItemBinding import com.idormy.sms.forwarder.databinding.AdapterRulesCardViewListItemBinding
@Suppress("EmptyMethod", "unused")
class RulePagingAdapter(private val itemClickListener: OnItemClickListener) : PagingDataAdapter<Rule, MyViewHolder>(diffCallback) { class RulePagingAdapter(private val itemClickListener: OnItemClickListener) : PagingDataAdapter<Rule, MyViewHolder>(diffCallback) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {

View File

@ -11,6 +11,7 @@ import com.idormy.sms.forwarder.adapter.SenderPagingAdapter.MyViewHolder
import com.idormy.sms.forwarder.database.entity.Sender import com.idormy.sms.forwarder.database.entity.Sender
import com.idormy.sms.forwarder.databinding.AdapterSendersCardViewListItemBinding import com.idormy.sms.forwarder.databinding.AdapterSendersCardViewListItemBinding
@Suppress("EmptyMethod", "unused")
class SenderPagingAdapter(private val itemClickListener: OnItemClickListener) : PagingDataAdapter<Sender, MyViewHolder>(diffCallback) { class SenderPagingAdapter(private val itemClickListener: OnItemClickListener) : PagingDataAdapter<Sender, MyViewHolder>(diffCallback) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {

View File

@ -18,6 +18,7 @@ import com.idormy.sms.forwarder.databinding.AdapterTasksCardViewListItemBinding
import com.idormy.sms.forwarder.entity.TaskSetting import com.idormy.sms.forwarder.entity.TaskSetting
import com.xuexiang.xutil.data.DateUtils import com.xuexiang.xutil.data.DateUtils
@Suppress("EmptyMethod", "unused")
class TaskPagingAdapter(private val itemClickListener: OnItemClickListener) : PagingDataAdapter<Task, MyViewHolder>(diffCallback) { class TaskPagingAdapter(private val itemClickListener: OnItemClickListener) : PagingDataAdapter<Task, MyViewHolder>(diffCallback) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION")
package com.idormy.sms.forwarder.adapter package com.idormy.sms.forwarder.adapter
import android.annotation.SuppressLint import android.annotation.SuppressLint
@ -14,6 +12,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.entity.TaskSetting import com.idormy.sms.forwarder.entity.TaskSetting
@Suppress("DEPRECATION", "unused")
class TaskSettingAdapter( class TaskSettingAdapter(
val itemList: MutableList<TaskSetting>, val itemList: MutableList<TaskSetting>,
private val editClickListener: (Int) -> Unit, private val editClickListener: (Int) -> Unit,
@ -90,11 +89,10 @@ class TaskSettingAdapter(
notifyItemMoved(fromPosition, toPosition) notifyItemMoved(fromPosition, toPosition)
} }
override fun onDragFinished() { override fun onDragFinished() {}
TODO("Not yet implemented")
}
} }
@Suppress("DEPRECATION")
class ItemMoveCallback(private val listener: Listener) : ItemTouchHelper.Callback() { class ItemMoveCallback(private val listener: Listener) : ItemTouchHelper.Callback() {
interface Listener { interface Listener {

View File

@ -12,6 +12,7 @@ import me.samlss.broccoli.Broccoli
* @author XUE * @author XUE
* @since 2019/4/8 16:33 * @since 2019/4/8 16:33
*/ */
@Suppress("unused")
abstract class BroccoliRecyclerAdapter<T>(collection: Collection<T>?) : abstract class BroccoliRecyclerAdapter<T>(collection: Collection<T>?) :
BaseRecyclerAdapter<T>(collection) { BaseRecyclerAdapter<T>(collection) {
/** /**

View File

@ -15,6 +15,7 @@ import me.samlss.broccoli.Broccoli
* @author xuexiang * @author xuexiang
* @since 2021/1/9 4:52 PM * @since 2021/1/9 4:52 PM
*/ */
@Suppress("unused")
abstract class BroccoliSimpleDelegateAdapter<T> : SimpleDelegateAdapter<T> { abstract class BroccoliSimpleDelegateAdapter<T> : SimpleDelegateAdapter<T> {
/** /**
* 是否已经加载成功 * 是否已经加载成功

View File

@ -9,6 +9,7 @@ import com.xuexiang.xui.adapter.recyclerview.RecyclerViewHolder
* @author xuexiang * @author xuexiang
* @since 2020/3/20 12:44 AM * @since 2020/3/20 12:44 AM
*/ */
@Suppress("unused")
abstract class BaseDelegateAdapter<T> : XDelegateAdapter<T, RecyclerViewHolder> { abstract class BaseDelegateAdapter<T> : XDelegateAdapter<T, RecyclerViewHolder> {
constructor() : super() constructor() : super()
constructor(list: Collection<T>?) : super(list) constructor(list: Collection<T>?) : super(list)

View File

@ -0,0 +1,83 @@
package com.idormy.sms.forwarder.adapter.menu
import android.util.SparseArray
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
@Suppress("LeakingThis", "UNCHECKED_CAST")
class DrawerAdapter(private val items: List<DrawerItem<out ViewHolder>>) : RecyclerView.Adapter<DrawerAdapter.ViewHolder>() {
private val viewTypes: MutableMap<Class<out DrawerItem<*>>, Int> = HashMap()
private val holderFactories = SparseArray<DrawerItem<*>>()
private var listener: OnItemSelectedListener? = null
init {
processViewTypes()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val holder = holderFactories.get(viewType).createViewHolder(parent)
holder.adapter = this
return holder
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
(items[position] as DrawerItem<ViewHolder>).bindViewHolder(holder)
}
override fun getItemCount(): Int = items.size
override fun getItemViewType(position: Int): Int = viewTypes[items[position]::class.java] ?: -1
private fun processViewTypes() {
var type = 0
items.forEach { item ->
if (!viewTypes.containsKey(item::class.java)) {
viewTypes[item::class.java] = type
holderFactories.put(type, item)
type++
}
}
}
fun setSelected(position: Int) {
val newChecked = items[position]
if (!newChecked.isSelectable()) return
items.forEachIndexed { index, item ->
if (item.isChecked()) {
item.setChecked(false)
notifyItemChanged(index)
return@forEachIndexed
}
}
newChecked.setChecked(true)
notifyItemChanged(position)
listener?.onItemSelected(position)
}
fun setListener(listener: OnItemSelectedListener?) {
this.listener = listener
}
@Suppress("DEPRECATION")
abstract class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
var adapter: DrawerAdapter? = null
init {
itemView.setOnClickListener(this)
}
override fun onClick(v: View) {
adapter?.setSelected(adapterPosition)
}
}
interface OnItemSelectedListener {
fun onItemSelected(position: Int)
}
}

View File

@ -0,0 +1,19 @@
package com.idormy.sms.forwarder.adapter.menu
import android.view.ViewGroup
abstract class DrawerItem<T : DrawerAdapter.ViewHolder> {
private var isChecked = false
abstract fun createViewHolder(parent: ViewGroup): T
abstract fun bindViewHolder(holder: T)
fun setChecked(checked: Boolean): DrawerItem<T> {
isChecked = checked
return this
}
fun isChecked(): Boolean = isChecked
open fun isSelectable(): Boolean = true
}

View File

@ -0,0 +1,54 @@
package com.idormy.sms.forwarder.adapter.menu
import android.graphics.drawable.Drawable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import com.idormy.sms.forwarder.R
class SimpleItem(
private val icon: Drawable,
private val title: String,
private var selectedItemIconTint: Int = 0,
private var selectedItemTextTint: Int = 0,
private var normalItemIconTint: Int = 0,
private var normalItemTextTint: Int = 0
) : DrawerItem<SimpleItem.ViewHolder>() {
override fun createViewHolder(parent: ViewGroup): ViewHolder {
val inflater = LayoutInflater.from(parent.context)
val v = inflater.inflate(R.layout.menu_item_option, parent, false)
return ViewHolder(v)
}
override fun bindViewHolder(holder: ViewHolder) {
holder.title.text = title
holder.icon.setImageDrawable(icon)
holder.title.setTextColor(if (isChecked()) selectedItemTextTint else normalItemTextTint)
holder.icon.setColorFilter(if (isChecked()) selectedItemIconTint else normalItemIconTint)
}
fun withSelectedIconTint(selectedItemIconTint: Int): SimpleItem = apply {
this.selectedItemIconTint = selectedItemIconTint
}
fun withSelectedTextTint(selectedItemTextTint: Int): SimpleItem = apply {
this.selectedItemTextTint = selectedItemTextTint
}
fun withIconTint(normalItemIconTint: Int): SimpleItem = apply {
this.normalItemIconTint = normalItemIconTint
}
fun withTextTint(normalItemTextTint: Int): SimpleItem = apply {
this.normalItemTextTint = normalItemTextTint
}
class ViewHolder(itemView: View) : DrawerAdapter.ViewHolder(itemView) {
val icon: ImageView = itemView.findViewById(R.id.icon)
val title: TextView = itemView.findViewById(R.id.title)
}
}

View File

@ -0,0 +1,24 @@
package com.idormy.sms.forwarder.adapter.menu
import android.content.Context
import android.view.View
import android.view.ViewGroup
class SpaceItem(private val spaceDp: Int) : DrawerItem<SpaceItem.ViewHolder>() {
override fun createViewHolder(parent: ViewGroup): ViewHolder {
val context: Context = parent.context
val view = View(context).apply {
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, (context.resources.displayMetrics.density * spaceDp).toInt()
)
}
return ViewHolder(view)
}
override fun bindViewHolder(holder: ViewHolder) {}
override fun isSelectable(): Boolean = false
class ViewHolder(itemView: View) : DrawerAdapter.ViewHolder(itemView)
}

View File

@ -76,8 +76,8 @@ class SenderSpinnerAdapter<T> : BaseEditSpinnerAdapter<T>, EditSpinnerFilter {
holder.statusView.setImageDrawable( holder.statusView.setImageDrawable(
ResUtils.getDrawable( ResUtils.getDrawable(
when (item.status) { when (item.status) {
STATUS_OFF -> R.drawable.icon_off STATUS_OFF -> R.drawable.ic_stop
else -> R.drawable.icon_on else -> R.drawable.ic_start
} }
) )
) )

View File

@ -26,7 +26,7 @@ import io.github.inflationx.viewpump.ViewPumpContextWrapper
* @author XUE * @author XUE
* @since 2019/3/22 11:21 * @since 2019/3/22 11:21
*/ */
@Suppress("MemberVisibilityCanBePrivate", "UNCHECKED_CAST", "DEPRECATION") @Suppress("MemberVisibilityCanBePrivate", "UNCHECKED_CAST", "DEPRECATION", "EmptyMethod")
open class BaseActivity<Binding : ViewBinding?> : XPageActivity() { open class BaseActivity<Binding : ViewBinding?> : XPageActivity() {
/** /**
* 获取Binding * 获取Binding

View File

@ -16,7 +16,7 @@ import com.xuexiang.xui.widget.actionbar.TitleUtils
* @author xuexiang * @author xuexiang
* @since 2018/11/22 上午11:26 * @since 2018/11/22 上午11:26
*/ */
@Suppress("unused", "UNUSED_PARAMETER") @Suppress("UNUSED_PARAMETER", "unused")
abstract class BaseContainerFragment : XPageContainerListFragment() { abstract class BaseContainerFragment : XPageContainerListFragment() {
override fun initPage() { override fun initPage() {
initTitle() initTitle()

View File

@ -35,7 +35,7 @@ import java.lang.reflect.Type
* @author xuexiang * @author xuexiang
* @since 2018/5/25 下午3:44 * @since 2018/5/25 下午3:44
*/ */
@Suppress("MemberVisibilityCanBePrivate") @Suppress("MemberVisibilityCanBePrivate", "EmptyMethod")
abstract class BaseFragment<Binding : ViewBinding?> : XPageFragment() { abstract class BaseFragment<Binding : ViewBinding?> : XPageFragment() {
private var mIProgressLoader: IProgressLoader? = null private var mIProgressLoader: IProgressLoader? = null
@ -204,27 +204,35 @@ abstract class BaseFragment<Binding : ViewBinding?> : XPageFragment() {
is Int -> { is Int -> {
option.putInt(key, value) option.putInt(key, value)
} }
is Float -> { is Float -> {
option.putFloat(key, value) option.putFloat(key, value)
} }
is String -> { is String -> {
option.putString(key, value) option.putString(key, value)
} }
is Boolean -> { is Boolean -> {
option.putBoolean(key, value) option.putBoolean(key, value)
} }
is Long -> { is Long -> {
option.putLong(key, value) option.putLong(key, value)
} }
is Double -> { is Double -> {
option.putDouble(key, value) option.putDouble(key, value)
} }
is Parcelable -> { is Parcelable -> {
option.putParcelable(key, value) option.putParcelable(key, value)
} }
is Serializable -> { is Serializable -> {
option.putSerializable(key, value) option.putSerializable(key, value)
} }
else -> { else -> {
option.putString(key, serializeObject(value)) option.putString(key, serializeObject(value))
} }

View File

@ -5,10 +5,14 @@ import android.util.Log
import androidx.work.Configuration import androidx.work.Configuration
import com.idormy.sms.forwarder.App import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.BuildConfig import com.idormy.sms.forwarder.BuildConfig
import com.idormy.sms.forwarder.database.repository.* import com.idormy.sms.forwarder.database.repository.FrpcRepository
import com.idormy.sms.forwarder.database.repository.LogsRepository
import com.idormy.sms.forwarder.database.repository.MsgRepository
import com.idormy.sms.forwarder.database.repository.RuleRepository
import com.idormy.sms.forwarder.database.repository.SenderRepository
import com.idormy.sms.forwarder.database.repository.TaskRepository
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@Suppress("unused")
object Core : Configuration.Provider { object Core : Configuration.Provider {
lateinit var app: Application lateinit var app: Application
val frpc: FrpcRepository by lazy { (app as App).frpcRepository } val frpc: FrpcRepository by lazy { (app as App).frpcRepository }

View File

@ -13,6 +13,7 @@ import com.xuexiang.xutil.common.StringUtils
* @author xuexiang * @author xuexiang
* @since 2018/12/19 上午12:19 * @since 2018/12/19 上午12:19
*/ */
@Suppress("unused")
class SimpleListAdapter(context: Context?, data: List<Map<String?, String?>?>?) : class SimpleListAdapter(context: Context?, data: List<Map<String?, String?>?>?) :
BaseListAdapter<Map<String?, String?>, SimpleListAdapter.ViewHolder>(context, data) { BaseListAdapter<Map<String?, String?>, SimpleListAdapter.ViewHolder>(context, data) {
override fun newViewHolder(convertView: View): ViewHolder { override fun newViewHolder(convertView: View): ViewHolder {

View File

@ -11,7 +11,6 @@ import com.just.agentweb.core.AgentWeb
* @author xuexiang * @author xuexiang
* @since 2019/5/28 10:22 * @since 2019/5/28 10:22
*/ */
@Suppress("unused")
abstract class BaseWebViewFragment : BaseFragment<ViewBinding?>() { abstract class BaseWebViewFragment : BaseFragment<ViewBinding?>() {
private var mAgentWeb: AgentWeb? = null private var mAgentWeb: AgentWeb? = null

View File

@ -11,7 +11,7 @@ import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.webview.WebViewInterceptDialog.Companion.show import com.idormy.sms.forwarder.core.webview.WebViewInterceptDialog.Companion.show
import com.just.agentweb.core.client.MiddlewareWebClientBase import com.just.agentweb.core.client.MiddlewareWebClientBase
import com.xuexiang.xui.utils.ResUtils import com.xuexiang.xui.utils.ResUtils
import java.util.* import java.util.Locale
/** /**
* 网络请求加载 * 网络请求加载
@ -47,7 +47,7 @@ import java.util.*
* *
* 这里主要是做去广告的工作 * 这里主要是做去广告的工作
*/ */
@Suppress("UNUSED_PARAMETER", "DEPRECATION", "OVERRIDE_DEPRECATION") @Suppress("UNUSED_PARAMETER", "DEPRECATION", "OVERRIDE_DEPRECATION", "unused")
open class MiddlewareWebViewClient : MiddlewareWebClientBase() { open class MiddlewareWebViewClient : MiddlewareWebClientBase() {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean { override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {

View File

@ -108,8 +108,8 @@ data class Rule(
val statusImageId: Int val statusImageId: Int
get() = when (status) { get() = when (status) {
STATUS_OFF -> R.drawable.icon_off STATUS_OFF -> R.drawable.ic_stop
else -> R.drawable.icon_on else -> R.drawable.ic_start
} }
fun getSenderLogicCheckId(): Int { fun getSenderLogicCheckId(): Int {

View File

@ -60,8 +60,8 @@ data class Sender(
val statusImageId: Int val statusImageId: Int
get() = when (status) { get() = when (status) {
STATUS_OFF -> R.drawable.icon_off STATUS_OFF -> R.drawable.ic_stop
else -> R.drawable.icon_on else -> R.drawable.ic_start
} }
} }

View File

@ -32,8 +32,8 @@ data class Task(
val statusImageId: Int val statusImageId: Int
get() = when (status) { get() = when (status) {
STATUS_OFF -> R.drawable.icon_off STATUS_OFF -> R.drawable.ic_stop
else -> R.drawable.icon_on else -> R.drawable.ic_start
} }
} }

View File

@ -3,7 +3,6 @@ package com.idormy.sms.forwarder.database.ext
import androidx.room.TypeConverter import androidx.room.TypeConverter
import java.util.Date import java.util.Date
@Suppress("unused")
class ConvertersDate { class ConvertersDate {
@TypeConverter @TypeConverter
fun fromTimestamp(value: Long?): Date? { fun fromTimestamp(value: Long?): Date? {

View File

@ -4,7 +4,6 @@ import androidx.room.TypeConverter
import com.idormy.sms.forwarder.core.Core import com.idormy.sms.forwarder.core.Core
import com.idormy.sms.forwarder.database.entity.Sender import com.idormy.sms.forwarder.database.entity.Sender
@Suppress("unused")
class ConvertersSenderList { class ConvertersSenderList {
@TypeConverter @TypeConverter

View File

@ -4,6 +4,5 @@ import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
@Suppress("unused")
fun <T> LifecycleOwner.observe(liveData: LiveData<T>?, observer: (T) -> Unit) = fun <T> LifecycleOwner.observe(liveData: LiveData<T>?, observer: (T) -> Unit) =
liveData?.observe(this, Observer(observer)) liveData?.observe(this, Observer(observer))

View File

@ -7,6 +7,7 @@ import com.xuexiang.xui.utils.ResUtils.getString
import java.io.Serializable import java.io.Serializable
import java.util.* import java.util.*
@Suppress("DEPRECATION")
data class ContactInfo( data class ContactInfo(
val name: String = "", val name: String = "",
@SerializedName("phone_number") @SerializedName("phone_number")

View File

@ -4,6 +4,7 @@ import com.idormy.sms.forwarder.R
import com.xuexiang.xui.utils.ResUtils import com.xuexiang.xui.utils.ResUtils
import java.io.Serializable import java.io.Serializable
@Suppress("DEPRECATION")
data class LocationInfo( data class LocationInfo(
var longitude: Double = 0.0, var longitude: Double = 0.0,
var latitude: Double = 0.0, var latitude: Double = 0.0,

View File

@ -6,7 +6,7 @@ import com.xuexiang.xui.utils.ResUtils
import com.xuexiang.xutil.resource.ResUtils.getString import com.xuexiang.xutil.resource.ResUtils.getString
import java.io.Serializable import java.io.Serializable
@Suppress("DEPRECATION", "unused") @Suppress("DEPRECATION")
data class ChargeSetting( data class ChargeSetting(
var description: String = "", //描述 var description: String = "", //描述
var status: Int = BatteryManager.BATTERY_STATUS_UNKNOWN, //状态 var status: Int = BatteryManager.BATTERY_STATUS_UNKNOWN, //状态

View File

@ -31,7 +31,7 @@ import com.xuexiang.xui.utils.WidgetUtils
import com.xuexiang.xui.widget.actionbar.TitleBar import com.xuexiang.xui.widget.actionbar.TitleBar
import com.xuexiang.xutil.XUtil import com.xuexiang.xutil.XUtil
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName", "DEPRECATION")
@Page(name = "应用列表") @Page(name = "应用列表")
class AppListFragment : BaseFragment<FragmentAppListBinding?>() { class AppListFragment : BaseFragment<FragmentAppListBinding?>() {

View File

@ -45,7 +45,7 @@ import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
import com.xuexiang.xutil.XUtil import com.xuexiang.xutil.XUtil
import com.xuexiang.xutil.data.ConvertTools import com.xuexiang.xutil.data.ConvertTools
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName", "DEPRECATION")
@Page(name = "主动控制·客户端") @Page(name = "主动控制·客户端")
class ClientFragment : BaseFragment<FragmentClientBinding?>(), View.OnClickListener, RecyclerViewHolder.OnItemClickListener<PageInfo> { class ClientFragment : BaseFragment<FragmentClientBinding?>(), View.OnClickListener, RecyclerViewHolder.OnItemClickListener<PageInfo> {

View File

@ -11,8 +11,10 @@ import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView.RecycledViewPool import androidx.recyclerview.widget.RecyclerView.RecycledViewPool
import com.alibaba.android.vlayout.VirtualLayoutManager import com.alibaba.android.vlayout.VirtualLayoutManager
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.activity.MainActivity
import com.idormy.sms.forwarder.adapter.MsgPagingAdapter import com.idormy.sms.forwarder.adapter.MsgPagingAdapter
import com.idormy.sms.forwarder.core.BaseFragment import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.database.AppDatabase
import com.idormy.sms.forwarder.database.entity.LogsDetail import com.idormy.sms.forwarder.database.entity.LogsDetail
import com.idormy.sms.forwarder.database.entity.MsgAndLogs import com.idormy.sms.forwarder.database.entity.MsgAndLogs
import com.idormy.sms.forwarder.database.entity.Rule import com.idormy.sms.forwarder.database.entity.Rule
@ -25,12 +27,17 @@ import com.idormy.sms.forwarder.utils.SendUtils
import com.idormy.sms.forwarder.utils.XToastUtils import com.idormy.sms.forwarder.utils.XToastUtils
import com.jeremyliao.liveeventbus.LiveEventBus import com.jeremyliao.liveeventbus.LiveEventBus
import com.scwang.smartrefresh.layout.api.RefreshLayout import com.scwang.smartrefresh.layout.api.RefreshLayout
import com.xuexiang.xaop.annotation.SingleClick
import com.xuexiang.xpage.annotation.Page import com.xuexiang.xpage.annotation.Page
import com.xuexiang.xui.utils.ResUtils import com.xuexiang.xui.utils.ResUtils
import com.xuexiang.xui.widget.actionbar.TitleBar import com.xuexiang.xui.widget.actionbar.TitleBar
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
import com.xuexiang.xutil.data.DateUtils import com.xuexiang.xutil.data.DateUtils
import io.reactivex.CompletableObserver
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -41,6 +48,7 @@ import java.util.*
class LogsFragment : BaseFragment<FragmentLogsBinding?>(), MsgPagingAdapter.OnItemClickListener { class LogsFragment : BaseFragment<FragmentLogsBinding?>(), MsgPagingAdapter.OnItemClickListener {
private val TAG: String = LogsFragment::class.java.simpleName private val TAG: String = LogsFragment::class.java.simpleName
private var titleBar: TitleBar? = null
private var adapter = MsgPagingAdapter(this) private var adapter = MsgPagingAdapter(this)
private val viewModel by viewModels<MsgViewModel> { BaseViewModelFactory(context) } private val viewModel by viewModels<MsgViewModel> { BaseViewModelFactory(context) }
private var currentType: String = "sms" private var currentType: String = "sms"
@ -52,11 +60,49 @@ class LogsFragment : BaseFragment<FragmentLogsBinding?>(), MsgPagingAdapter.OnIt
return FragmentLogsBinding.inflate(inflater, container, false) return FragmentLogsBinding.inflate(inflater, container, false)
} }
/**
* @return 返回为 null意为不需要导航栏
*/
override fun initTitle(): TitleBar? { override fun initTitle(): TitleBar? {
return null titleBar = super.initTitle()!!.setImmersive(false)
titleBar!!.setLeftImageResource(R.drawable.ic_action_menu)
titleBar!!.setTitle(R.string.menu_logs)
titleBar!!.setLeftClickListener { getContainer()?.openMenu() }
/*titleBar!!.addAction(object : TitleBar.ImageAction(R.drawable.ic_menu_notifications_white) {
@SingleClick
override fun performAction(view: View) {
showTipsForce(requireContext())
}
})*/
titleBar!!.addAction(object : TitleBar.ImageAction(R.drawable.ic_delete) {
@SingleClick
override fun performAction(view: View) {
MaterialDialog.Builder(requireContext())
.content(R.string.delete_type_log_tips)
.positiveText(R.string.lab_yes)
.negativeText(R.string.lab_no)
.onPositive { _: MaterialDialog?, _: DialogAction? ->
AppDatabase.getInstance(requireContext())
.msgDao()
.deleteAll(currentType)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : CompletableObserver {
override fun onSubscribe(d: Disposable) {}
override fun onComplete() {
XToastUtils.success(R.string.delete_type_log_toast)
}
override fun onError(e: Throwable) {
e.message?.let { XToastUtils.error(it) }
}
})
}
.show()
}
})
return titleBar
}
private fun getContainer(): MainActivity? {
return activity as MainActivity?
} }
/** /**

View File

@ -474,7 +474,7 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
val tvSenderName = layoutSenderItem.findViewById<TextView>(R.id.tv_sender_name) val tvSenderName = layoutSenderItem.findViewById<TextView>(R.id.tv_sender_name)
ivSenderImage.setImageDrawable(sender.icon) ivSenderImage.setImageDrawable(sender.icon)
ivSenderStatus.setImageDrawable(ResUtils.getDrawable(if (STATUS_OFF == sender.status) R.drawable.icon_off else R.drawable.icon_on)) ivSenderStatus.setImageDrawable(ResUtils.getDrawable(if (STATUS_OFF == sender.status) R.drawable.ic_stop else R.drawable.ic_start))
val senderItemId = sender.id as Long val senderItemId = sender.id as Long
tvSenderName.text = "ID-$senderItemId${sender.title}" tvSenderName.text = "ID-$senderItemId${sender.title}"

View File

@ -8,6 +8,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView.RecycledViewPool import androidx.recyclerview.widget.RecyclerView.RecycledViewPool
import com.alibaba.android.vlayout.VirtualLayoutManager import com.alibaba.android.vlayout.VirtualLayoutManager
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.activity.MainActivity
import com.idormy.sms.forwarder.adapter.RulePagingAdapter import com.idormy.sms.forwarder.adapter.RulePagingAdapter
import com.idormy.sms.forwarder.core.BaseFragment import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.database.entity.Rule import com.idormy.sms.forwarder.database.entity.Rule
@ -21,6 +22,7 @@ import com.idormy.sms.forwarder.utils.KEY_RULE_TYPE
import com.idormy.sms.forwarder.utils.XToastUtils import com.idormy.sms.forwarder.utils.XToastUtils
import com.jeremyliao.liveeventbus.LiveEventBus import com.jeremyliao.liveeventbus.LiveEventBus
import com.scwang.smartrefresh.layout.api.RefreshLayout import com.scwang.smartrefresh.layout.api.RefreshLayout
import com.xuexiang.xaop.annotation.SingleClick
import com.xuexiang.xpage.annotation.Page import com.xuexiang.xpage.annotation.Page
import com.xuexiang.xpage.core.PageOption import com.xuexiang.xpage.core.PageOption
import com.xuexiang.xui.utils.ResUtils import com.xuexiang.xui.utils.ResUtils
@ -35,7 +37,9 @@ import kotlinx.coroutines.launch
class RulesFragment : BaseFragment<FragmentRulesBinding?>(), RulePagingAdapter.OnItemClickListener { class RulesFragment : BaseFragment<FragmentRulesBinding?>(), RulePagingAdapter.OnItemClickListener {
//private val TAG: String = RulesFragment::class.java.simpleName //private val TAG: String = RulesFragment::class.java.simpleName
private val that = this
private var adapter = RulePagingAdapter(this) private var adapter = RulePagingAdapter(this)
private var titleBar: TitleBar? = null
private val viewModel by viewModels<RuleViewModel> { BaseViewModelFactory(context) } private val viewModel by viewModels<RuleViewModel> { BaseViewModelFactory(context) }
private var currentType: String = "sms" private var currentType: String = "sms"
@ -46,11 +50,25 @@ class RulesFragment : BaseFragment<FragmentRulesBinding?>(), RulePagingAdapter.O
return FragmentRulesBinding.inflate(inflater, container, false) return FragmentRulesBinding.inflate(inflater, container, false)
} }
/**
* @return 返回为 null意为不需要导航栏
*/
override fun initTitle(): TitleBar? { override fun initTitle(): TitleBar? {
return null titleBar = super.initTitle()!!.setImmersive(false)
titleBar!!.setLeftImageResource(R.drawable.ic_action_menu)
titleBar!!.setTitle(R.string.menu_rules)
titleBar!!.setLeftClickListener { getContainer()?.openMenu() }
titleBar!!.addAction(object : TitleBar.ImageAction(R.drawable.ic_add) {
@SingleClick
override fun performAction(view: View) {
PageOption.to(RulesEditFragment::class.java)
.putString(KEY_RULE_TYPE, currentType)
.setNewActivity(true)
.open(that)
}
})
return titleBar
}
private fun getContainer(): MainActivity? {
return activity as MainActivity?
} }
/** /**
@ -132,5 +150,4 @@ class RulesFragment : BaseFragment<FragmentRulesBinding?>(), RulePagingAdapter.O
} }
override fun onItemRemove(view: View?, id: Int) {} override fun onItemRemove(view: View?, id: Int) {}
} }

View File

@ -1,15 +1,20 @@
package com.idormy.sms.forwarder.fragment package com.idormy.sms.forwarder.fragment
import android.annotation.SuppressLint
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.RecycledViewPool import androidx.recyclerview.widget.RecyclerView.RecycledViewPool
import com.alibaba.android.vlayout.VirtualLayoutManager import com.alibaba.android.vlayout.VirtualLayoutManager
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.activity.MainActivity
import com.idormy.sms.forwarder.adapter.SenderPagingAdapter import com.idormy.sms.forwarder.adapter.SenderPagingAdapter
import com.idormy.sms.forwarder.adapter.WidgetItemAdapter
import com.idormy.sms.forwarder.core.BaseFragment import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.database.entity.Sender import com.idormy.sms.forwarder.database.entity.Sender
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
@ -34,6 +39,7 @@ import com.idormy.sms.forwarder.fragment.senders.WeworkRobotFragment
import com.idormy.sms.forwarder.utils.KEY_SENDER_CLONE import com.idormy.sms.forwarder.utils.KEY_SENDER_CLONE
import com.idormy.sms.forwarder.utils.KEY_SENDER_ID import com.idormy.sms.forwarder.utils.KEY_SENDER_ID
import com.idormy.sms.forwarder.utils.KEY_SENDER_TYPE import com.idormy.sms.forwarder.utils.KEY_SENDER_TYPE
import com.idormy.sms.forwarder.utils.SENDER_FRAGMENT_LIST
import com.idormy.sms.forwarder.utils.TYPE_BARK import com.idormy.sms.forwarder.utils.TYPE_BARK
import com.idormy.sms.forwarder.utils.TYPE_DINGTALK_GROUP_ROBOT import com.idormy.sms.forwarder.utils.TYPE_DINGTALK_GROUP_ROBOT
import com.idormy.sms.forwarder.utils.TYPE_DINGTALK_INNER_ROBOT import com.idormy.sms.forwarder.utils.TYPE_DINGTALK_INNER_ROBOT
@ -52,10 +58,17 @@ import com.idormy.sms.forwarder.utils.TYPE_WEWORK_AGENT
import com.idormy.sms.forwarder.utils.TYPE_WEWORK_ROBOT import com.idormy.sms.forwarder.utils.TYPE_WEWORK_ROBOT
import com.idormy.sms.forwarder.utils.XToastUtils import com.idormy.sms.forwarder.utils.XToastUtils
import com.scwang.smartrefresh.layout.api.RefreshLayout import com.scwang.smartrefresh.layout.api.RefreshLayout
import com.xuexiang.xaop.annotation.SingleClick
import com.xuexiang.xpage.annotation.Page import com.xuexiang.xpage.annotation.Page
import com.xuexiang.xpage.base.XPageFragment
import com.xuexiang.xpage.core.PageOption import com.xuexiang.xpage.core.PageOption
import com.xuexiang.xpage.model.PageInfo
import com.xuexiang.xui.adapter.recyclerview.RecyclerViewHolder
import com.xuexiang.xui.utils.DensityUtils
import com.xuexiang.xui.utils.ResUtils import com.xuexiang.xui.utils.ResUtils
import com.xuexiang.xui.utils.WidgetUtils
import com.xuexiang.xui.widget.actionbar.TitleBar import com.xuexiang.xui.widget.actionbar.TitleBar
import com.xuexiang.xui.widget.alpha.XUIAlphaTextView
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.collectLatest
@ -63,11 +76,16 @@ import kotlinx.coroutines.launch
@Suppress("PrivatePropertyName", "DEPRECATION") @Suppress("PrivatePropertyName", "DEPRECATION")
@Page(name = "发送通道") @Page(name = "发送通道")
class SendersFragment : BaseFragment<FragmentSendersBinding?>(), SenderPagingAdapter.OnItemClickListener { class SendersFragment : BaseFragment<FragmentSendersBinding?>(),
SenderPagingAdapter.OnItemClickListener,
RecyclerViewHolder.OnItemClickListener<PageInfo> {
private val TAG: String = SendersFragment::class.java.simpleName private val TAG: String = SendersFragment::class.java.simpleName
private val that = this
private var titleBar: TitleBar? = null
private var adapter = SenderPagingAdapter(this) private var adapter = SenderPagingAdapter(this)
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) } private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
private val dialog: BottomSheetDialog by lazy { BottomSheetDialog(requireContext()) }
private var currentStatus: Int = 1 private var currentStatus: Int = 1
//private val statusValueArray = ResUtils.getIntArray(R.array.status_param_value) //private val statusValueArray = ResUtils.getIntArray(R.array.status_param_value)
@ -78,11 +96,38 @@ class SendersFragment : BaseFragment<FragmentSendersBinding?>(), SenderPagingAda
return FragmentSendersBinding.inflate(inflater, container, false) return FragmentSendersBinding.inflate(inflater, container, false)
} }
/**
* @return 返回为 null意为不需要导航栏
*/
override fun initTitle(): TitleBar? { override fun initTitle(): TitleBar? {
return null titleBar = super.initTitle()!!.setImmersive(false)
titleBar!!.setLeftImageResource(R.drawable.ic_action_menu)
titleBar!!.setTitle(R.string.menu_senders)
titleBar!!.setLeftClickListener { getContainer()?.openMenu() }
titleBar!!.addAction(object : TitleBar.ImageAction(R.drawable.ic_add) {
@SuppressLint("InflateParams")
@SingleClick
override fun performAction(view: View) {
val bottomSheet: View = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_sender_bottom_sheet, null)
val recyclerView: RecyclerView = bottomSheet.findViewById(R.id.recyclerView)
WidgetUtils.initGridRecyclerView(recyclerView, 4, DensityUtils.dp2px(1f))
val widgetItemAdapter = WidgetItemAdapter(SENDER_FRAGMENT_LIST)
widgetItemAdapter.setOnItemClickListener(that)
recyclerView.adapter = widgetItemAdapter
val bottomSheetCloseButton: XUIAlphaTextView = bottomSheet.findViewById(R.id.bottom_sheet_close_button)
bottomSheetCloseButton.setOnClickListener { dialog.dismiss() }
dialog.setContentView(bottomSheet)
dialog.setCancelable(true)
dialog.setCanceledOnTouchOutside(true)
dialog.show()
WidgetUtils.transparentBottomSheetDialogBackground(dialog)
}
})
return titleBar
}
private fun getContainer(): MainActivity? {
return activity as MainActivity?
} }
/** /**
@ -127,27 +172,8 @@ class SendersFragment : BaseFragment<FragmentSendersBinding?>(), SenderPagingAda
Log.e(TAG, item.toString()) Log.e(TAG, item.toString())
when (view?.id) { when (view?.id) {
R.id.iv_copy -> { R.id.iv_copy -> {
PageOption.to( PageOption.to(getFragment(item.type))
when (item.type) { .setNewActivity(true)
TYPE_DINGTALK_GROUP_ROBOT -> DingtalkGroupRobotFragment::class.java
TYPE_EMAIL -> EmailFragment::class.java
TYPE_BARK -> BarkFragment::class.java
TYPE_WEBHOOK -> WebhookFragment::class.java
TYPE_WEWORK_ROBOT -> WeworkRobotFragment::class.java
TYPE_WEWORK_AGENT -> WeworkAgentFragment::class.java
TYPE_SERVERCHAN -> ServerchanFragment::class.java
TYPE_TELEGRAM -> TelegramFragment::class.java
TYPE_SMS -> SmsFragment::class.java
TYPE_FEISHU -> FeishuFragment::class.java
TYPE_PUSHPLUS -> PushplusFragment::class.java
TYPE_GOTIFY -> GotifyFragment::class.java
TYPE_DINGTALK_INNER_ROBOT -> DingtalkInnerRobotFragment::class.java
TYPE_FEISHU_APP -> FeishuAppFragment::class.java
TYPE_URL_SCHEME -> UrlSchemeFragment::class.java
TYPE_SOCKET -> SocketFragment::class.java
else -> DingtalkGroupRobotFragment::class.java
}
).setNewActivity(true)
.putLong(KEY_SENDER_ID, item.id) .putLong(KEY_SENDER_ID, item.id)
.putInt(KEY_SENDER_TYPE, item.type) .putInt(KEY_SENDER_TYPE, item.type)
.putBoolean(KEY_SENDER_CLONE, true) .putBoolean(KEY_SENDER_CLONE, true)
@ -155,27 +181,8 @@ class SendersFragment : BaseFragment<FragmentSendersBinding?>(), SenderPagingAda
} }
R.id.iv_edit -> { R.id.iv_edit -> {
PageOption.to( PageOption.to(getFragment(item.type))
when (item.type) { .setNewActivity(true)
TYPE_DINGTALK_GROUP_ROBOT -> DingtalkGroupRobotFragment::class.java
TYPE_EMAIL -> EmailFragment::class.java
TYPE_BARK -> BarkFragment::class.java
TYPE_WEBHOOK -> WebhookFragment::class.java
TYPE_WEWORK_ROBOT -> WeworkRobotFragment::class.java
TYPE_WEWORK_AGENT -> WeworkAgentFragment::class.java
TYPE_SERVERCHAN -> ServerchanFragment::class.java
TYPE_TELEGRAM -> TelegramFragment::class.java
TYPE_SMS -> SmsFragment::class.java
TYPE_FEISHU -> FeishuFragment::class.java
TYPE_PUSHPLUS -> PushplusFragment::class.java
TYPE_GOTIFY -> GotifyFragment::class.java
TYPE_DINGTALK_INNER_ROBOT -> DingtalkInnerRobotFragment::class.java
TYPE_FEISHU_APP -> FeishuAppFragment::class.java
TYPE_URL_SCHEME -> UrlSchemeFragment::class.java
TYPE_SOCKET -> SocketFragment::class.java
else -> DingtalkGroupRobotFragment::class.java
}
).setNewActivity(true)
.putLong(KEY_SENDER_ID, item.id) .putLong(KEY_SENDER_ID, item.id)
.putInt(KEY_SENDER_TYPE, item.type) .putInt(KEY_SENDER_TYPE, item.type)
.open(this) .open(this)
@ -200,4 +207,40 @@ class SendersFragment : BaseFragment<FragmentSendersBinding?>(), SenderPagingAda
override fun onItemRemove(view: View?, id: Int) {} override fun onItemRemove(view: View?, id: Int) {}
@SingleClick
override fun onItemClick(itemView: View, widgetInfo: PageInfo, pos: Int) {
try {
@Suppress("UNCHECKED_CAST")
PageOption.to(Class.forName(widgetInfo.classPath) as Class<XPageFragment>) //跳转的fragment
.setNewActivity(true)
.putInt(KEY_SENDER_TYPE, pos) //注意:目前刚好是这个顺序而已
.open(this)
} catch (e: Exception) {
e.printStackTrace()
XToastUtils.error(e.message.toString())
}
}
private fun getFragment(type: Int): Class<out XPageFragment> {
return when (type) {
TYPE_DINGTALK_GROUP_ROBOT -> DingtalkGroupRobotFragment::class.java
TYPE_EMAIL -> EmailFragment::class.java
TYPE_BARK -> BarkFragment::class.java
TYPE_WEBHOOK -> WebhookFragment::class.java
TYPE_WEWORK_ROBOT -> WeworkRobotFragment::class.java
TYPE_WEWORK_AGENT -> WeworkAgentFragment::class.java
TYPE_SERVERCHAN -> ServerchanFragment::class.java
TYPE_TELEGRAM -> TelegramFragment::class.java
TYPE_SMS -> SmsFragment::class.java
TYPE_FEISHU -> FeishuFragment::class.java
TYPE_PUSHPLUS -> PushplusFragment::class.java
TYPE_GOTIFY -> GotifyFragment::class.java
TYPE_DINGTALK_INNER_ROBOT -> DingtalkInnerRobotFragment::class.java
TYPE_FEISHU_APP -> FeishuAppFragment::class.java
TYPE_URL_SCHEME -> UrlSchemeFragment::class.java
TYPE_SOCKET -> SocketFragment::class.java
else -> DingtalkGroupRobotFragment::class.java
}
}
} }

View File

@ -28,6 +28,7 @@ import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions import com.hjq.permissions.XXPermissions
import com.idormy.sms.forwarder.App import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.R import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.activity.MainActivity
import com.idormy.sms.forwarder.adapter.spinner.AppListAdapterItem import com.idormy.sms.forwarder.adapter.spinner.AppListAdapterItem
import com.idormy.sms.forwarder.adapter.spinner.AppListSpinnerAdapter import com.idormy.sms.forwarder.adapter.spinner.AppListSpinnerAdapter
import com.idormy.sms.forwarder.core.BaseFragment import com.idormy.sms.forwarder.core.BaseFragment
@ -37,6 +38,7 @@ import com.idormy.sms.forwarder.receiver.BootCompletedReceiver
import com.idormy.sms.forwarder.service.ForegroundService import com.idormy.sms.forwarder.service.ForegroundService
import com.idormy.sms.forwarder.service.LocationService import com.idormy.sms.forwarder.service.LocationService
import com.idormy.sms.forwarder.utils.* import com.idormy.sms.forwarder.utils.*
import com.idormy.sms.forwarder.widget.GuideTipsDialog
import com.idormy.sms.forwarder.workers.LoadAppListWorker import com.idormy.sms.forwarder.workers.LoadAppListWorker
import com.jeremyliao.liveeventbus.LiveEventBus import com.jeremyliao.liveeventbus.LiveEventBus
import com.xuexiang.xaop.annotation.SingleClick import com.xuexiang.xaop.annotation.SingleClick
@ -60,6 +62,7 @@ import java.util.*
class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickListener { class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickListener {
private val TAG: String = SettingsFragment::class.java.simpleName private val TAG: String = SettingsFragment::class.java.simpleName
private var titleBar: TitleBar? = null
private val mTimeOption = DataProvider.timePeriodOption private val mTimeOption = DataProvider.timePeriodOption
//已安装App信息列表 //已安装App信息列表
@ -77,15 +80,38 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
return FragmentSettingsBinding.inflate(inflater, container, false) return FragmentSettingsBinding.inflate(inflater, container, false)
} }
/**
* @return 返回为 null意为不需要导航栏
*/
override fun initTitle(): TitleBar? { override fun initTitle(): TitleBar? {
return null titleBar = super.initTitle()!!.setImmersive(false)
titleBar!!.setLeftImageResource(R.drawable.ic_action_menu)
titleBar!!.setTitle(R.string.menu_settings)
titleBar!!.setLeftClickListener { getContainer()?.openMenu() }
titleBar!!.addAction(object : TitleBar.ImageAction(R.drawable.ic_menu_notifications_white) {
@SingleClick
override fun performAction(view: View) {
GuideTipsDialog.showTipsForce(requireContext())
}
})/*titleBar!!.addAction(object : TitleBar.ImageAction(R.drawable.ic_restore) {
@SingleClick
override fun performAction(view: View) {
MaterialDialog.Builder(requireContext())
.content(R.string.delete_type_log_tips)
.positiveText(R.string.lab_yes)
.negativeText(R.string.lab_no)
.onPositive { _: MaterialDialog?, _: DialogAction? ->
}
.show()
}
})*/
return titleBar
}
private fun getContainer(): MainActivity? {
return activity as MainActivity?
} }
@SuppressLint("NewApi", "SetTextI18n") @SuppressLint("NewApi", "SetTextI18n")
override fun initViews() { override fun initViews() {
//转发短信广播 //转发短信广播
switchEnableSms(binding!!.sbEnableSms) switchEnableSms(binding!!.sbEnableSms)
//转发通话记录 //转发通话记录
@ -94,7 +120,7 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
switchEnableAppNotify(binding!!.sbEnableAppNotify, binding!!.scbCancelAppNotify, binding!!.scbNotUserPresent) switchEnableAppNotify(binding!!.sbEnableAppNotify, binding!!.scbCancelAppNotify, binding!!.scbNotUserPresent)
//启用GPS定位功能 //启用GPS定位功能
switchEnableLocation(binding!!.sbEnableLocation, binding!!.layoutLocationSetting, binding!!.rgAccuracy, binding!!.rgPowerRequirement, binding!!.xsbMinInterval, binding!!.xsbMinDistance) switchEnableLocation(binding!!.sbEnableLocation, binding!!.layoutLocationSetting, binding!!.rgAccuracy, binding!!.rgPowerRequirement, binding!!.etMinInterval, binding!!.etMinDistance)
//短信指令 //短信指令
switchEnableSmsCommand(binding!!.sbEnableSmsCommand, binding!!.etSafePhone) switchEnableSmsCommand(binding!!.sbEnableSmsCommand, binding!!.etSafePhone)
//启动时异步获取已安装App信息 //启动时异步获取已安装App信息
@ -140,6 +166,7 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
switchDirectlyToClient(binding!!.sbDirectlyToClient) switchDirectlyToClient(binding!!.sbDirectlyToClient)
//纯自动任务模式 //纯自动任务模式
switchDirectlyToTask(binding!!.sbDirectlyToTask) switchDirectlyToTask(binding!!.sbDirectlyToTask)
} }
override fun onResume() { override fun onResume() {
@ -456,7 +483,7 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
} }
//启用定位功能 //启用定位功能
private fun switchEnableLocation(@SuppressLint("UseSwitchCompatOrMaterialCode") switchEnableLocation: SwitchButton, layoutLocationSetting: LinearLayout, rgAccuracy: RadioGroup, rgPowerRequirement: RadioGroup, xsbMinInterval: XSeekBar, xsbMinDistance: XSeekBar) { private fun switchEnableLocation(@SuppressLint("UseSwitchCompatOrMaterialCode") switchEnableLocation: SwitchButton, layoutLocationSetting: LinearLayout, rgAccuracy: RadioGroup, rgPowerRequirement: RadioGroup, etMinInterval: EditText, etMinDistance: EditText) {
//是否启用定位功能 //是否启用定位功能
switchEnableLocation.isChecked = SettingUtils.enableLocation switchEnableLocation.isChecked = SettingUtils.enableLocation
layoutLocationSetting.visibility = if (SettingUtils.enableLocation) View.VISIBLE else View.GONE layoutLocationSetting.visibility = if (SettingUtils.enableLocation) View.VISIBLE else View.GONE
@ -486,6 +513,7 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
} }
layoutLocationSetting.visibility = if (isChecked) View.VISIBLE else View.GONE layoutLocationSetting.visibility = if (isChecked) View.VISIBLE else View.GONE
} }
//设置位置精度:高精度(默认) //设置位置精度:高精度(默认)
rgAccuracy.check( rgAccuracy.check(
when (SettingUtils.locationAccuracy) { when (SettingUtils.locationAccuracy) {
@ -502,9 +530,9 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
R.id.rb_accuracy_no_requirement -> Criteria.NO_REQUIREMENT R.id.rb_accuracy_no_requirement -> Criteria.NO_REQUIREMENT
else -> Criteria.ACCURACY_FINE else -> Criteria.ACCURACY_FINE
} }
//TODO: MainActivity.kt 中压入 FragmentManager 时会导致定位服务重启,暂时注释掉 restartLocationService("rgAccuracy")
//restartLocationService()
} }
//设置电量消耗:低电耗(默认) //设置电量消耗:低电耗(默认)
rgPowerRequirement.check( rgPowerRequirement.check(
when (SettingUtils.locationPowerRequirement) { when (SettingUtils.locationPowerRequirement) {
@ -523,23 +551,42 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
R.id.rb_power_requirement_no_requirement -> Criteria.NO_REQUIREMENT R.id.rb_power_requirement_no_requirement -> Criteria.NO_REQUIREMENT
else -> Criteria.POWER_LOW else -> Criteria.POWER_LOW
} }
//TODO: MainActivity.kt 中压入 FragmentManager 时会导致定位服务重启,暂时注释掉 restartLocationService("rgPowerRequirement")
//restartLocationService()
} }
//设置位置更新最小时间间隔(单位:毫秒); 默认间隔10000毫秒最小间隔1000毫秒 //设置位置更新最小时间间隔(单位:毫秒); 默认间隔10000毫秒最小间隔1000毫秒
xsbMinInterval.setDefaultValue((SettingUtils.locationMinInterval / 1000).toInt()) etMinInterval.setText((SettingUtils.locationMinInterval / 1000).toString())
xsbMinInterval.setOnSeekBarListener { _: XSeekBar?, newValue: Int -> etMinInterval.addTextChangedListener(object : TextWatcher {
SettingUtils.locationMinInterval = newValue * 1000L override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
//TODO: MainActivity.kt 中压入 FragmentManager 时会导致定位服务重启,暂时注释掉 override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
//restartLocationService() override fun afterTextChanged(s: Editable) {
} val changedText = s.toString()
if (changedText.isEmpty() || changedText == "0") {
etMinInterval.setText("1")
etMinInterval.setSelection(etMinInterval.text.length) // 将光标移至文本末尾
return
}
SettingUtils.locationMinInterval = changedText.toLong() * 1000
restartLocationService()
}
})
//设置位置更新最小距离单位默认距离0米 //设置位置更新最小距离单位默认距离0米
xsbMinDistance.setDefaultValue(SettingUtils.locationMinDistance) etMinDistance.setText(SettingUtils.locationMinDistance.toString())
xsbMinDistance.setOnSeekBarListener { _: XSeekBar?, newValue: Int -> etMinDistance.addTextChangedListener(object : TextWatcher {
SettingUtils.locationMinDistance = newValue override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
//TODO: MainActivity.kt 中压入 FragmentManager 时会导致定位服务重启,暂时注释掉 override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
//restartLocationService() override fun afterTextChanged(s: Editable) {
} val changedText = s.toString()
if (changedText.isEmpty()) {
etMinDistance.setText("0")
etMinDistance.setSelection(etMinInterval.text.length) // 将光标移至文本末尾
return
}
SettingUtils.locationMinDistance = changedText.toInt()
restartLocationService()
}
})
} }
//重启定位服务 //重启定位服务
@ -772,6 +819,7 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
xsbRetryTimes.setDefaultValue(SettingUtils.requestRetryTimes) xsbRetryTimes.setDefaultValue(SettingUtils.requestRetryTimes)
xsbRetryTimes.setOnSeekBarListener { _: XSeekBar?, newValue: Int -> xsbRetryTimes.setOnSeekBarListener { _: XSeekBar?, newValue: Int ->
SettingUtils.requestRetryTimes = newValue SettingUtils.requestRetryTimes = newValue
binding!!.layoutDelayTime.visibility = if (newValue > 0) View.VISIBLE else View.GONE
} }
xsbDelayTime.setDefaultValue(SettingUtils.requestDelayTime) xsbDelayTime.setDefaultValue(SettingUtils.requestDelayTime)
xsbDelayTime.setOnSeekBarListener { _: XSeekBar?, newValue: Int -> xsbDelayTime.setOnSeekBarListener { _: XSeekBar?, newValue: Int ->

View File

@ -53,16 +53,14 @@ import java.util.*
@Page(name = "自动任务·编辑器") @Page(name = "自动任务·编辑器")
@Suppress("PrivatePropertyName", "unused", "DEPRECATION", "UNUSED_PARAMETER") @Suppress("PrivatePropertyName", "DEPRECATION", "UNUSED_PARAMETER", "EmptyMethod", "unused")
class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClickListener, RecyclerViewHolder.OnItemClickListener<PageInfo> { class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClickListener, RecyclerViewHolder.OnItemClickListener<PageInfo> {
private val TAG: String = TasksEditFragment::class.java.simpleName private val TAG: String = TasksEditFragment::class.java.simpleName
private val that = this private val that = this
private var titleBar: TitleBar? = null private var titleBar: TitleBar? = null
private val viewModel by viewModels<TaskViewModel> { BaseViewModelFactory(context) } private val viewModel by viewModels<TaskViewModel> { BaseViewModelFactory(context) }
private val dialog: BottomSheetDialog by lazy { private val dialog: BottomSheetDialog by lazy { BottomSheetDialog(requireContext()) }
BottomSheetDialog(requireContext())
}
@JvmField @JvmField
@AutoWired(name = KEY_TASK_ID) @AutoWired(name = KEY_TASK_ID)
@ -170,20 +168,20 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
try { try {
when (v.id) { when (v.id) {
R.id.layout_add_condition -> { R.id.layout_add_condition -> {
val view: View = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_task_condition_bottom_sheet, null) val bottomSheet: View = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_task_condition_bottom_sheet, null)
val tvTitle: TextView = view.findViewById(R.id.tv_title) val tvTitle: TextView = bottomSheet.findViewById(R.id.tv_title)
tvTitle.text = if (itemListConditions.isEmpty()) getString(R.string.select_task_trigger) else getString(R.string.select_task_condition) tvTitle.text = if (itemListConditions.isEmpty()) getString(R.string.select_task_trigger) else getString(R.string.select_task_condition)
val recyclerView: RecyclerView = view.findViewById(R.id.recyclerView) val recyclerView: RecyclerView = bottomSheet.findViewById(R.id.recyclerView)
WidgetUtils.initGridRecyclerView(recyclerView, 4, DensityUtils.dp2px(1f)) WidgetUtils.initGridRecyclerView(recyclerView, 4, DensityUtils.dp2px(1f))
val widgetItemAdapter = WidgetItemAdapter(TASK_CONDITION_FRAGMENT_LIST) val widgetItemAdapter = WidgetItemAdapter(TASK_CONDITION_FRAGMENT_LIST)
widgetItemAdapter.setOnItemClickListener(that) widgetItemAdapter.setOnItemClickListener(that)
recyclerView.adapter = widgetItemAdapter recyclerView.adapter = widgetItemAdapter
val bottomSheetCloseButton: XUIAlphaTextView = view.findViewById(R.id.bottom_sheet_close_button) val bottomSheetCloseButton: XUIAlphaTextView = bottomSheet.findViewById(R.id.bottom_sheet_close_button)
bottomSheetCloseButton.setOnClickListener { dialog.dismiss() } bottomSheetCloseButton.setOnClickListener { dialog.dismiss() }
dialog.setContentView(view) dialog.setContentView(bottomSheet)
dialog.setCancelable(true) dialog.setCancelable(true)
dialog.setCanceledOnTouchOutside(true) dialog.setCanceledOnTouchOutside(true)
dialog.show() dialog.show()
@ -191,18 +189,18 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
} }
R.id.layout_add_action -> { R.id.layout_add_action -> {
val view: View = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_task_action_bottom_sheet, null) val bottomSheet: View = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_task_action_bottom_sheet, null)
val recyclerView: RecyclerView = view.findViewById(R.id.recyclerView) val recyclerView: RecyclerView = bottomSheet.findViewById(R.id.recyclerView)
WidgetUtils.initGridRecyclerView(recyclerView, 4, DensityUtils.dp2px(1f)) WidgetUtils.initGridRecyclerView(recyclerView, 4, DensityUtils.dp2px(1f))
val widgetItemAdapter = WidgetItemAdapter(TASK_ACTION_FRAGMENT_LIST) val widgetItemAdapter = WidgetItemAdapter(TASK_ACTION_FRAGMENT_LIST)
widgetItemAdapter.setOnItemClickListener(that) widgetItemAdapter.setOnItemClickListener(that)
recyclerView.adapter = widgetItemAdapter recyclerView.adapter = widgetItemAdapter
val bottomSheetCloseButton: XUIAlphaTextView = view.findViewById(R.id.bottom_sheet_close_button) val bottomSheetCloseButton: XUIAlphaTextView = bottomSheet.findViewById(R.id.bottom_sheet_close_button)
bottomSheetCloseButton.setOnClickListener { dialog.dismiss() } bottomSheetCloseButton.setOnClickListener { dialog.dismiss() }
dialog.setContentView(view) dialog.setContentView(bottomSheet)
dialog.setCancelable(true) dialog.setCancelable(true)
dialog.setCanceledOnTouchOutside(true) dialog.setCanceledOnTouchOutside(true)
dialog.show() dialog.show()

View File

@ -378,7 +378,7 @@ class NotificationFragment : BaseFragment<FragmentTasksActionNotificationBinding
val tvSenderName = layoutSenderItem.findViewById<TextView>(R.id.tv_sender_name) val tvSenderName = layoutSenderItem.findViewById<TextView>(R.id.tv_sender_name)
ivSenderImage.setImageDrawable(sender.icon) ivSenderImage.setImageDrawable(sender.icon)
ivSenderStatus.setImageDrawable(ResUtils.getDrawable(if (STATUS_OFF == sender.status) R.drawable.icon_off else R.drawable.icon_on)) ivSenderStatus.setImageDrawable(ResUtils.getDrawable(if (STATUS_OFF == sender.status) R.drawable.ic_stop else R.drawable.ic_start))
val senderItemId = sender.id as Long val senderItemId = sender.id as Long
tvSenderName.text = "ID-$senderItemId${sender.title}" tvSenderName.text = "ID-$senderItemId${sender.title}"

View File

@ -134,9 +134,6 @@ class CallQueryFragment : BaseFragment<FragmentClientCallQueryBinding?>() {
.addPlaceholder(PlaceholderHelper.getParameter(holder.findView(R.id.iv_reply))) .addPlaceholder(PlaceholderHelper.getParameter(holder.findView(R.id.iv_reply)))
} }
override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) {
TODO("Not yet implemented")
}
} }
val delegateAdapter = DelegateAdapter(virtualLayoutManager) val delegateAdapter = DelegateAdapter(virtualLayoutManager)

View File

@ -125,9 +125,6 @@ class ContactQueryFragment : BaseFragment<FragmentClientContactQueryBinding?>()
.addPlaceholder(PlaceholderHelper.getParameter(holder.findView(R.id.iv_reply))) .addPlaceholder(PlaceholderHelper.getParameter(holder.findView(R.id.iv_reply)))
} }
override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) {
TODO("Not yet implemented")
}
} }
val delegateAdapter = DelegateAdapter(virtualLayoutManager) val delegateAdapter = DelegateAdapter(virtualLayoutManager)

View File

@ -122,10 +122,6 @@ class SmsQueryFragment : BaseFragment<FragmentClientSmsQueryBinding?>() {
.addPlaceholder(PlaceholderHelper.getParameter(holder.findView(R.id.iv_reply))) .addPlaceholder(PlaceholderHelper.getParameter(holder.findView(R.id.iv_reply)))
} }
override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) {
TODO("Not yet implemented")
}
} }
val delegateAdapter = DelegateAdapter(virtualLayoutManager) val delegateAdapter = DelegateAdapter(virtualLayoutManager)

View File

@ -24,7 +24,7 @@ import com.xuexiang.xrouter.launcher.XRouter
import com.xuexiang.xui.widget.actionbar.TitleBar import com.xuexiang.xui.widget.actionbar.TitleBar
@Page(name = "Battery") @Page(name = "Battery")
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName", "SameParameterValue")
class BatteryFragment : BaseFragment<FragmentTasksConditionBatteryBinding?>(), View.OnClickListener { class BatteryFragment : BaseFragment<FragmentTasksConditionBatteryBinding?>(), View.OnClickListener {
private val TAG: String = BatteryFragment::class.java.simpleName private val TAG: String = BatteryFragment::class.java.simpleName

View File

@ -23,7 +23,7 @@ import com.xuexiang.xrouter.launcher.XRouter
import com.xuexiang.xui.widget.actionbar.TitleBar import com.xuexiang.xui.widget.actionbar.TitleBar
@Page(name = "Charge") @Page(name = "Charge")
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName", "SameParameterValue")
class ChargeFragment : BaseFragment<FragmentTasksConditionChargeBinding?>(), View.OnClickListener { class ChargeFragment : BaseFragment<FragmentTasksConditionChargeBinding?>(), View.OnClickListener {
private val TAG: String = ChargeFragment::class.java.simpleName private val TAG: String = ChargeFragment::class.java.simpleName

View File

@ -31,7 +31,7 @@ import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
@Page(name = "LeaveAddress") @Page(name = "LeaveAddress")
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName", "SameParameterValue")
class LeaveAddressFragment : BaseFragment<FragmentTasksConditionLeaveAddressBinding?>(), View.OnClickListener { class LeaveAddressFragment : BaseFragment<FragmentTasksConditionLeaveAddressBinding?>(), View.OnClickListener {
private val TAG: String = LeaveAddressFragment::class.java.simpleName private val TAG: String = LeaveAddressFragment::class.java.simpleName
@ -78,17 +78,18 @@ class LeaveAddressFragment : BaseFragment<FragmentTasksConditionLeaveAddressBind
} }
} }
Log.d(TAG, "initViews eventData:$eventData") var settingVo = LocationSetting(getString(R.string.task_leave_address_tips), "leave")
if (eventData != null) { if (eventData != null) {
val settingVo = Gson().fromJson(eventData, LocationSetting::class.java) Log.d(TAG, "initViews eventData:$eventData")
Log.d(TAG, "initViews settingVo:$settingVo") settingVo = Gson().fromJson(eventData, LocationSetting::class.java)
binding!!.tvDescription.text = settingVo.description
binding!!.etLongitude.setText(settingVo.longitude.toString())
binding!!.etLatitude.setText(settingVo.latitude.toString())
binding!!.etDistance.setText(settingVo.distance.toString())
binding!!.etAddress.setText(settingVo.address)
binding!!.rgCalcType.check(settingVo.getCalcTypeCheckId())
} }
Log.d(TAG, "initViews settingVo:$settingVo")
binding!!.tvDescription.text = settingVo.description
binding!!.etLongitude.setText(settingVo.longitude.toString())
binding!!.etLatitude.setText(settingVo.latitude.toString())
binding!!.etDistance.setText(settingVo.distance.toString())
binding!!.etAddress.setText(settingVo.address)
binding!!.rgCalcType.check(settingVo.getCalcTypeCheckId())
} }
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
@ -220,7 +221,7 @@ class LeaveAddressFragment : BaseFragment<FragmentTasksConditionLeaveAddressBind
if (latitude.isNaN() || longitude.isNaN() || distance.isNaN()) { if (latitude.isNaN() || longitude.isNaN() || distance.isNaN()) {
throw Exception(getString(R.string.calc_type_distance_error)) throw Exception(getString(R.string.calc_type_distance_error))
} }
description = String.format(getString(R.string.to_address_distance_description), longitude, latitude, distance) description = String.format(getString(R.string.leave_address_distance_description), longitude, latitude, distance)
"distance" "distance"
} }
@ -228,7 +229,7 @@ class LeaveAddressFragment : BaseFragment<FragmentTasksConditionLeaveAddressBind
if (address.isEmpty()) { if (address.isEmpty()) {
throw Exception(getString(R.string.calc_type_address_error)) throw Exception(getString(R.string.calc_type_address_error))
} }
description = String.format(getString(R.string.to_address_keyword_description), address) description = String.format(getString(R.string.leave_address_keyword_description), address)
"address" "address"
} }
} }

View File

@ -23,7 +23,7 @@ import com.xuexiang.xrouter.launcher.XRouter
import com.xuexiang.xui.widget.actionbar.TitleBar import com.xuexiang.xui.widget.actionbar.TitleBar
@Page(name = "LockScreen") @Page(name = "LockScreen")
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName", "SameParameterValue")
class LockScreenFragment : BaseFragment<FragmentTasksConditionLockScreenBinding?>(), View.OnClickListener { class LockScreenFragment : BaseFragment<FragmentTasksConditionLockScreenBinding?>(), View.OnClickListener {
private val TAG: String = LockScreenFragment::class.java.simpleName private val TAG: String = LockScreenFragment::class.java.simpleName

View File

@ -25,7 +25,7 @@ import com.xuexiang.xrouter.launcher.XRouter
import com.xuexiang.xui.widget.actionbar.TitleBar import com.xuexiang.xui.widget.actionbar.TitleBar
@Page(name = "Network") @Page(name = "Network")
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName", "SameParameterValue")
class NetworkFragment : BaseFragment<FragmentTasksConditionNetworkBinding?>(), View.OnClickListener { class NetworkFragment : BaseFragment<FragmentTasksConditionNetworkBinding?>(), View.OnClickListener {
private val TAG: String = NetworkFragment::class.java.simpleName private val TAG: String = NetworkFragment::class.java.simpleName

View File

@ -23,7 +23,7 @@ import com.xuexiang.xrouter.launcher.XRouter
import com.xuexiang.xui.widget.actionbar.TitleBar import com.xuexiang.xui.widget.actionbar.TitleBar
@Page(name = "Sim") @Page(name = "Sim")
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName", "SameParameterValue")
class SimFragment : BaseFragment<FragmentTasksConditionSimBinding?>(), View.OnClickListener { class SimFragment : BaseFragment<FragmentTasksConditionSimBinding?>(), View.OnClickListener {
private val TAG: String = SimFragment::class.java.simpleName private val TAG: String = SimFragment::class.java.simpleName

View File

@ -31,7 +31,7 @@ import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
@Page(name = "ToAddress") @Page(name = "ToAddress")
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName", "SameParameterValue")
class ToAddressFragment : BaseFragment<FragmentTasksConditionToAddressBinding?>(), View.OnClickListener { class ToAddressFragment : BaseFragment<FragmentTasksConditionToAddressBinding?>(), View.OnClickListener {
private val TAG: String = ToAddressFragment::class.java.simpleName private val TAG: String = ToAddressFragment::class.java.simpleName
@ -78,17 +78,18 @@ class ToAddressFragment : BaseFragment<FragmentTasksConditionToAddressBinding?>(
} }
} }
Log.d(TAG, "initViews eventData:$eventData") var settingVo = LocationSetting(getString(R.string.task_leave_address_tips), "to")
if (eventData != null) { if (eventData != null) {
val settingVo = Gson().fromJson(eventData, LocationSetting::class.java) Log.d(TAG, "initViews eventData:$eventData")
Log.d(TAG, "initViews settingVo:$settingVo") settingVo = Gson().fromJson(eventData, LocationSetting::class.java)
binding!!.tvDescription.text = settingVo.description
binding!!.etLongitude.setText(settingVo.longitude.toString())
binding!!.etLatitude.setText(settingVo.latitude.toString())
binding!!.etDistance.setText(settingVo.distance.toString())
binding!!.etAddress.setText(settingVo.address)
binding!!.rgCalcType.check(settingVo.getCalcTypeCheckId())
} }
Log.d(TAG, "initViews settingVo:$settingVo")
binding!!.tvDescription.text = settingVo.description
binding!!.etLongitude.setText(settingVo.longitude.toString())
binding!!.etLatitude.setText(settingVo.latitude.toString())
binding!!.etDistance.setText(settingVo.distance.toString())
binding!!.etAddress.setText(settingVo.address)
binding!!.rgCalcType.check(settingVo.getCalcTypeCheckId())
} }
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")

View File

@ -44,7 +44,7 @@ import io.reactivex.schedulers.Schedulers
import java.util.Date import java.util.Date
@Page(name = "Email") @Page(name = "Email")
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName", "DEPRECATION")
class EmailFragment : BaseFragment<FragmentSendersEmailBinding?>(), View.OnClickListener { class EmailFragment : BaseFragment<FragmentSendersEmailBinding?>(), View.OnClickListener {
private val TAG: String = EmailFragment::class.java.simpleName private val TAG: String = EmailFragment::class.java.simpleName

View File

@ -157,15 +157,9 @@ class WebhookFragment : BaseFragment<FragmentSendersWebhookBinding?>(), View.OnC
binding!!.btnDel.setOnClickListener(this) binding!!.btnDel.setOnClickListener(this)
binding!!.btnSave.setOnClickListener(this) binding!!.btnSave.setOnClickListener(this)
binding!!.btnAddHeader.setOnClickListener { binding!!.btnAddHeader.setOnClickListener {
addHeaderItemLinearLayout( addHeaderItemLinearLayout(headerItemMap, binding!!.layoutHeaders, null, null)
headerItemMap,
binding!!.layoutHeaders,
null,
null
)
} }
LiveEventBus.get(KEY_SENDER_TEST, String::class.java) LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
.observe(this) { mCountDownHelper?.finish() }
} }
@SingleClick @SingleClick

View File

@ -22,7 +22,7 @@ import com.idormy.sms.forwarder.utils.TaskWorker
import com.idormy.sms.forwarder.utils.task.TaskUtils import com.idormy.sms.forwarder.utils.task.TaskUtils
import com.idormy.sms.forwarder.workers.NetworkWorker import com.idormy.sms.forwarder.workers.NetworkWorker
@Suppress("PrivatePropertyName", "DEPRECATION", "UNUSED_PARAMETER") @Suppress("PrivatePropertyName", "DEPRECATION", "UNUSED_PARAMETER", "unused")
class NetworkChangeReceiver : BroadcastReceiver() { class NetworkChangeReceiver : BroadcastReceiver() {
private val TAG: String = NetworkChangeReceiver::class.java.simpleName private val TAG: String = NetworkChangeReceiver::class.java.simpleName

View File

@ -6,9 +6,9 @@ import android.content.Intent
import android.telephony.TelephonyManager import android.telephony.TelephonyManager
import android.util.Log import android.util.Log
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import java.util.* import java.util.Date
@Suppress("DEPRECATION") @Suppress("DEPRECATION", "unused")
abstract class PhoneStateReceiver : BroadcastReceiver() { abstract class PhoneStateReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
@ -70,6 +70,7 @@ abstract class PhoneStateReceiver : BroadcastReceiver() {
onIncomingCallReceived(context, number, callStartTime) onIncomingCallReceived(context, number, callStartTime)
} }
TelephonyManager.CALL_STATE_OFFHOOK -> TelephonyManager.CALL_STATE_OFFHOOK ->
//Transition of ringing->offhook are pickups of incoming calls. Nothing done on them //Transition of ringing->offhook are pickups of incoming calls. Nothing done on them
if (lastState != TelephonyManager.CALL_STATE_RINGING) { if (lastState != TelephonyManager.CALL_STATE_RINGING) {
@ -83,6 +84,7 @@ abstract class PhoneStateReceiver : BroadcastReceiver() {
onIncomingCallAnswered(context, savedNumber, callStartTime) onIncomingCallAnswered(context, savedNumber, callStartTime)
} }
TelephonyManager.CALL_STATE_IDLE -> TelephonyManager.CALL_STATE_IDLE ->
//Went to idle- this is the end of a call. What type depends on previous state(s) //Went to idle- this is the end of a call. What type depends on previous state(s)
if (lastState == TelephonyManager.CALL_STATE_RINGING) { if (lastState == TelephonyManager.CALL_STATE_RINGING) {

View File

@ -20,7 +20,7 @@ import com.xuexiang.xrouter.utils.TextUtils
import java.util.Date import java.util.Date
//短信广播 //短信广播
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName", "unused", "UNUSED_PARAMETER")
class SmsReceiver : BroadcastReceiver() { class SmsReceiver : BroadcastReceiver() {
private var TAG = SmsReceiver::class.java.simpleName private var TAG = SmsReceiver::class.java.simpleName

View File

@ -13,7 +13,7 @@ import com.yanzhenjie.andserver.http.HttpMethod
import com.yanzhenjie.andserver.http.HttpRequest import com.yanzhenjie.andserver.http.HttpRequest
import com.yanzhenjie.andserver.http.HttpResponse import com.yanzhenjie.andserver.http.HttpResponse
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName", "DEPRECATION")
@Interceptor @Interceptor
class LoggerInterceptor : HandlerInterceptor { class LoggerInterceptor : HandlerInterceptor {

View File

@ -9,7 +9,6 @@ import com.yanzhenjie.andserver.http.HttpRequest
import com.yanzhenjie.andserver.http.HttpResponse import com.yanzhenjie.andserver.http.HttpResponse
//@Interceptor //@Interceptor
@Suppress("unused")
class LoginInterceptor : HandlerInterceptor { class LoginInterceptor : HandlerInterceptor {
override fun onIntercept( override fun onIntercept(
request: HttpRequest, request: HttpRequest,

View File

@ -12,7 +12,7 @@ import com.xuexiang.xutil.XUtil.getContentResolver
import com.yanzhenjie.andserver.annotation.* import com.yanzhenjie.andserver.annotation.*
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName", "SameReturnValue")
@RestController @RestController
@RequestMapping(path = ["/contact"]) @RequestMapping(path = ["/contact"])
class ContactController { class ContactController {

View File

@ -13,7 +13,7 @@ import kotlin.reflect.KProperty
* @author pppscn * @author pppscn
* @since 2022年5月9日 * @since 2022年5月9日
*/ */
@Suppress("UNCHECKED_CAST", "MemberVisibilityCanBePrivate", "unused") @Suppress("UNCHECKED_CAST", "unused")
class HistoryUtils<T>(private val name: String, private val default: T) : ReadWriteProperty<Any?, T> { class HistoryUtils<T>(private val name: String, private val default: T) : ReadWriteProperty<Any?, T> {
companion object { companion object {

View File

@ -11,7 +11,6 @@ import javax.crypto.Cipher
/** /**
* 非对称加密RSA加密和解密 * 非对称加密RSA加密和解密
*/ */
@Suppress("unused")
object RSACrypt { object RSACrypt {
private const val transformation = "RSA" private const val transformation = "RSA"

View File

@ -12,7 +12,6 @@ import com.xuexiang.xui.widget.toast.XToast
* @author xuexiang * @author xuexiang
* @since 2019-06-30 19:04 * @since 2019-06-30 19:04
*/ */
@Suppress("unused")
class XToastUtils private constructor() { class XToastUtils private constructor() {
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
companion object { companion object {

View File

@ -41,7 +41,7 @@ class UMengInit private constructor() {
return return
} }
UMConfigure.setLogEnabled(false) UMConfigure.setLogEnabled(false)
UMConfigure.preInit(application, BuildConfig.APP_ID_UMENG, getChannel()) //getChannel(application) UMConfigure.preInit(application, BuildConfig.APP_ID_UMENG, DEFAULT_CHANNEL_ID) //getChannel(application)
// 用户同意了隐私协议 // 用户同意了隐私协议
if (isAgreePrivacy) { if (isAgreePrivacy) {
realInit(application) realInit(application)
@ -62,7 +62,7 @@ class UMengInit private constructor() {
UMConfigure.init( UMConfigure.init(
application, application,
BuildConfig.APP_ID_UMENG, BuildConfig.APP_ID_UMENG,
getChannel(), //getChannel(application) DEFAULT_CHANNEL_ID, //getChannel(application)
UMConfigure.DEVICE_TYPE_PHONE, UMConfigure.DEVICE_TYPE_PHONE,
"" ""
) )
@ -75,10 +75,9 @@ class UMengInit private constructor() {
/** /**
* 获取渠道信息 * 获取渠道信息
*/ */
private fun getChannel(): String { //context: Context? //private fun getChannel(context: Context?): String {
//return WalleChannelReader.getChannel(context!!, DEFAULT_CHANNEL_ID) // return WalleChannelReader.getChannel(context!!, DEFAULT_CHANNEL_ID)
return DEFAULT_CHANNEL_ID //}
}
} }
init { init {

View File

@ -18,7 +18,7 @@ import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec import javax.crypto.spec.SecretKeySpec
@Suppress("unused", "RegExpRedundantEscape") @Suppress("RegExpRedundantEscape")
class BarkUtils { class BarkUtils {
companion object { companion object {

View File

@ -25,6 +25,7 @@ import com.zzhoujay.richtext.RichText
* @author xuexiang * @author xuexiang
* @since 2019-08-22 17:02 * @since 2019-08-22 17:02
*/ */
@Suppress("SameReturnValue")
class GuideTipsDialog(context: Context?, tips: List<TipInfo>) : class GuideTipsDialog(context: Context?, tips: List<TipInfo>) :
BaseDialog(context, R.layout.dialog_guide_tips), View.OnClickListener, BaseDialog(context, R.layout.dialog_guide_tips), View.OnClickListener,
CompoundButton.OnCheckedChangeListener { CompoundButton.OnCheckedChangeListener {
@ -85,10 +86,12 @@ class GuideTipsDialog(context: Context?, tips: List<TipInfo>) :
mTvPrevious!!.isEnabled = false mTvPrevious!!.isEnabled = false
mTvNext!!.isEnabled = true mTvNext!!.isEnabled = true
} }
mTips!!.size - 1 -> { mTips!!.size - 1 -> {
mTvPrevious!!.isEnabled = true mTvPrevious!!.isEnabled = true
mTvNext!!.isEnabled = false mTvNext!!.isEnabled = false
} }
else -> { else -> {
mTvPrevious!!.isEnabled = true mTvPrevious!!.isEnabled = true
mTvNext!!.isEnabled = true mTvNext!!.isEnabled = true

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorAccent" android:state_pressed="true" />
<item android:color="?attr/colorAccent" android:state_selected="true" />
<item android:color="@color/xui_btn_disable_color" android:state_enabled="false" />
<item android:color="?attr/colorAccent" />
</selector>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2018 xuexiangjys(xuexiangjys@163.com)
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="?attr/colorAccent" />
<item android:state_selected="true" android:color="?attr/colorAccent" />
<item android:color="@color/xui_config_color_gray_6" />
</selector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 543 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 397 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 434 B

View File

@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="#FFFFFF" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M11.67,3.87L9.9,2.1 0,12l9.9,9.9 1.77,-1.77L3.54,12z"/>
</vector>

View File

@ -0,0 +1,24 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#ffffff"
android:pathData="M895.11,191.93 L381.96,191.93c-35.15,0 -63.64,28.49 -63.64,63.64 0,35.15 28.49,63.64 63.64,63.64l513.15,0c35.15,0 63.64,-28.49 63.64,-63.64C958.75,220.43 930.26,191.93 895.11,191.93z" />
<path
android:fillColor="#ffffff"
android:pathData="M895.11,449.81 L381.96,449.81c-35.15,0 -63.64,28.49 -63.64,63.64 0,35.15 28.49,63.64 63.64,63.64l513.15,0c35.15,0 63.64,-28.49 63.64,-63.64C958.75,478.3 930.26,449.81 895.11,449.81z" />
<path
android:fillColor="#ffffff"
android:pathData="M893.06,703.59 L379.91,703.59c-35.15,0 -63.64,28.49 -63.64,63.64 0,35.15 28.49,63.64 63.64,63.64l513.15,0c35.15,0 63.64,-28.49 63.64,-63.64C956.7,732.08 928.21,703.59 893.06,703.59z" />
<path
android:fillColor="#ffffff"
android:pathData="M130.65,257.03m-61.4,0a60,60 0,1 0,122.8 0,60 60,0 1,0 -122.8,0Z" />
<path
android:fillColor="#ffffff"
android:pathData="M124.51,514.9m-61.4,0a60,60 0,1 0,122.8 0,60 60,0 1,0 -122.8,0Z" />
<path
android:fillColor="#ffffff"
android:pathData="M126.55,766.63m-61.4,0a60,60 0,1 0,122.8 0,60 60,0 1,0 -122.8,0Z" />
</vector>

View File

Before

Width:  |  Height:  |  Size: 414 B

After

Width:  |  Height:  |  Size: 414 B

View File

@ -4,6 +4,6 @@
android:viewportWidth="24.0" android:viewportWidth="24.0"
android:viewportHeight="24.0"> android:viewportHeight="24.0">
<path <path
android:fillColor="?attr/colorAccent" android:fillColor="?attr/colorControlNormal"
android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z" /> android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z" />
</vector> </vector>

View File

@ -4,6 +4,6 @@
android:viewportWidth="24.0" android:viewportWidth="24.0"
android:viewportHeight="24.0"> android:viewportHeight="24.0">
<path <path
android:fillColor="?attr/colorAccent" android:fillColor="?attr/colorControlNormal"
android:pathData="M4,8h4L8,4L4,4v4zM10,20h4v-4h-4v4zM4,20h4v-4L4,16v4zM4,14h4v-4L4,10v4zM10,14h4v-4h-4v4zM16,4v4h4L20,4h-4zM10,8h4L14,4h-4v4zM16,14h4v-4h-4v4zM16,20h4v-4h-4v4z" /> android:pathData="M4,8h4L8,4L4,4v4zM10,20h4v-4h-4v4zM4,20h4v-4L4,16v4zM4,14h4v-4L4,10v4zM10,14h4v-4h-4v4zM16,4v4h4L20,4h-4zM10,8h4L14,4h-4v4zM16,14h4v-4h-4v4zM16,20h4v-4h-4v4z" />
</vector> </vector>

View File

@ -4,6 +4,6 @@
android:viewportWidth="24.0" android:viewportWidth="24.0"
android:viewportHeight="24.0"> android:viewportHeight="24.0">
<path <path
android:fillColor="?attr/colorAccent" android:fillColor="?attr/colorControlNormal"
android:pathData="M20,18c1.1,0 1.99,-0.9 1.99,-2L22,6c0,-1.1 -0.9,-2 -2,-2H4c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2H0v2h24v-2h-4zM4,6h16v10H4V6z" /> android:pathData="M20,18c1.1,0 1.99,-0.9 1.99,-2L22,6c0,-1.1 -0.9,-2 -2,-2H4c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2H0v2h24v-2h-4zM4,6h16v10H4V6z" />
</vector> </vector>

View File

@ -4,6 +4,6 @@
android:viewportWidth="24.0" android:viewportWidth="24.0"
android:viewportHeight="24.0"> android:viewportHeight="24.0">
<path <path
android:fillColor="?attr/colorAccent" android:fillColor="?attr/colorControlNormal"
android:pathData="M7.77,6.76L6.23,5.48 0.82,12l5.41,6.52 1.54,-1.28L3.42,12l4.35,-5.24zM7,13h2v-2L7,11v2zM17,11h-2v2h2v-2zM11,13h2v-2h-2v2zM17.77,5.48l-1.54,1.28L20.58,12l-4.35,5.24 1.54,1.28L23.18,12l-5.41,-6.52z" /> android:pathData="M7.77,6.76L6.23,5.48 0.82,12l5.41,6.52 1.54,-1.28L3.42,12l4.35,-5.24zM7,13h2v-2L7,11v2zM17,11h-2v2h2v-2zM11,13h2v-2h-2v2zM17.77,5.48l-1.54,1.28L20.58,12l-4.35,5.24 1.54,1.28L23.18,12l-5.41,-6.52z" />
</vector> </vector>

View File

@ -4,6 +4,6 @@
android:viewportWidth="24.0" android:viewportWidth="24.0"
android:viewportHeight="24.0"> android:viewportHeight="24.0">
<path <path
android:fillColor="?attr/colorAccent" android:fillColor="?attr/colorControlNormal"
android:pathData="M11,18h2v-2h-2v2zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM12,6c-2.21,0 -4,1.79 -4,4h2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2c0,2 -3,1.75 -3,5h2c0,-2.25 3,-2.5 3,-5 0,-2.21 -1.79,-4 -4,-4z" /> android:pathData="M11,18h2v-2h-2v2zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM12,6c-2.21,0 -4,1.79 -4,4h2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2c0,2 -3,1.75 -3,5h2c0,-2.25 3,-2.5 3,-5 0,-2.21 -1.79,-4 -4,-4z" />
</vector> </vector>

View File

@ -1,12 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="?attr/colorAccent"
android:pathData="M19,3H5C3.9,3 3,3.9 3,5v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V5C21,3.9 20.1,3 19,3zM7.68,14.98H6V9h1.71c1.28,0 1.71,1.03 1.71,1.71l0,2.56C9.42,13.95 9,14.98 7.68,14.98zM12.38,11.46v1.07h-1.18v1.39h1.93v1.07h-2.25c-0.4,0.01 -0.74,-0.31 -0.75,-0.71V9.75c-0.01,-0.4 0.31,-0.74 0.71,-0.75h2.28l0,1.07h-1.92v1.39H12.38zM16.88,14.23c-0.48,1.11 -1.33,0.89 -1.71,0L13.77,9h1.18l1.07,4.11L17.09,9h1.18L16.88,14.23z" />
<path
android:fillColor="?attr/colorAccent"
android:pathData="M7.77,10.12H7.14v3.77h0.63c0.14,0 0.28,-0.05 0.42,-0.16c0.14,-0.1 0.21,-0.26 0.21,-0.47v-2.52c0,-0.21 -0.07,-0.37 -0.21,-0.47C8.05,10.17 7.91,10.12 7.77,10.12z" />
</vector>

View File

@ -4,6 +4,6 @@
android:viewportWidth="24.0" android:viewportWidth="24.0"
android:viewportHeight="24.0"> android:viewportHeight="24.0">
<path <path
android:fillColor="?attr/colorAccent" android:fillColor="?attr/colorControlNormal"
android:pathData="M19,5v14L5,19L5,5h14m1.1,-2L3.9,3c-0.5,0 -0.9,0.4 -0.9,0.9v16.2c0,0.4 0.4,0.9 0.9,0.9h16.2c0.4,0 0.9,-0.5 0.9,-0.9L21,3.9c0,-0.5 -0.5,-0.9 -0.9,-0.9zM11,7h6v2h-6L11,7zM11,11h6v2h-6v-2zM11,15h6v2h-6zM7,7h2v2L7,9zM7,11h2v2L7,13zM7,15h2v2L7,17z" /> android:pathData="M19,5v14L5,19L5,5h14m1.1,-2L3.9,3c-0.5,0 -0.9,0.4 -0.9,0.9v16.2c0,0.4 0.4,0.9 0.9,0.9h16.2c0.4,0 0.9,-0.5 0.9,-0.9L21,3.9c0,-0.5 -0.5,-0.9 -0.9,-0.9zM11,7h6v2h-6L11,7zM11,11h6v2h-6v-2zM11,15h6v2h-6zM7,7h2v2L7,9zM7,11h2v2L7,13zM7,15h2v2L7,17z" />
</vector> </vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="?attr/colorAccent"
android:pathData="M19,5v14L5,19L5,5h14m1.1,-2L3.9,3c-0.5,0 -0.9,0.4 -0.9,0.9v16.2c0,0.4 0.4,0.9 0.9,0.9h16.2c0.4,0 0.9,-0.5 0.9,-0.9L21,3.9c0,-0.5 -0.5,-0.9 -0.9,-0.9zM11,7h6v2h-6L11,7zM11,11h6v2h-6v-2zM11,15h6v2h-6zM7,7h2v2L7,9zM7,11h2v2L7,13zM7,15h2v2L7,17z" />
</vector>

View File

@ -4,6 +4,6 @@
android:viewportWidth="24.0" android:viewportWidth="24.0"
android:viewportHeight="24.0"> android:viewportHeight="24.0">
<path <path
android:fillColor="?attr/colorAccent" android:fillColor="?attr/colorControlNormal"
android:pathData="M16.54,11L13,7.46l1.41,-1.41l2.12,2.12l4.24,-4.24l1.41,1.41L16.54,11zM11,7H2v2h9V7zM21,13.41L19.59,12L17,14.59L14.41,12L13,13.41L15.59,16L13,18.59L14.41,20L17,17.41L19.59,20L21,18.59L18.41,16L21,13.41zM11,15H2v2h9V15z" /> android:pathData="M16.54,11L13,7.46l1.41,-1.41l2.12,2.12l4.24,-4.24l1.41,1.41L16.54,11zM11,7H2v2h9V7zM21,13.41L19.59,12L17,14.59L14.41,12L13,13.41L15.59,16L13,18.59L14.41,20L17,17.41L19.59,20L21,18.59L18.41,16L21,13.41zM11,15H2v2h9V15z" />
</vector> </vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="?attr/colorAccent"
android:pathData="M16.54,11L13,7.46l1.41,-1.41l2.12,2.12l4.24,-4.24l1.41,1.41L16.54,11zM11,7H2v2h9V7zM21,13.41L19.59,12L17,14.59L14.41,12L13,13.41L15.59,16L13,18.59L14.41,20L17,17.41L19.59,20L21,18.59L18.41,16L21,13.41zM11,15H2v2h9V15z" />
</vector>

View File

@ -4,6 +4,6 @@
android:viewportWidth="24.0" android:viewportWidth="24.0"
android:viewportHeight="24.0"> android:viewportHeight="24.0">
<path <path
android:fillColor="?attr/colorAccent" android:fillColor="?attr/colorControlNormal"
android:pathData="M2.01,21L23,12 2.01,3 2,10l15,2 -15,2z" /> android:pathData="M2.01,21L23,12 2.01,3 2,10l15,2 -15,2z" />
</vector> </vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="?attr/colorAccent"
android:pathData="M2.01,21L23,12 2.01,3 2,10l15,2 -15,2z" />
</vector>

View File

@ -4,6 +4,6 @@
android:viewportWidth="24.0" android:viewportWidth="24.0"
android:viewportHeight="24.0"> android:viewportHeight="24.0">
<path <path
android:fillColor="?attr/colorAccent" android:fillColor="?attr/colorControlNormal"
android:pathData="M14,12l-2,2l-2,-2l2,-2L14,12zM12,6l2.12,2.12l2.5,-2.5L12,1L7.38,5.62l2.5,2.5L12,6zM6,12l2.12,-2.12l-2.5,-2.5L1,12l4.62,4.62l2.5,-2.5L6,12zM18,12l-2.12,2.12l2.5,2.5L23,12l-4.62,-4.62l-2.5,2.5L18,12zM12,18l-2.12,-2.12l-2.5,2.5L12,23l4.62,-4.62l-2.5,-2.5L12,18z" /> android:pathData="M14,12l-2,2l-2,-2l2,-2L14,12zM12,6l2.12,2.12l2.5,-2.5L12,1L7.38,5.62l2.5,2.5L12,6zM6,12l2.12,-2.12l-2.5,-2.5L1,12l4.62,4.62l2.5,-2.5L6,12zM18,12l-2.12,2.12l2.5,2.5L23,12l-4.62,-4.62l-2.5,2.5L18,12zM12,18l-2.12,-2.12l-2.5,2.5L12,23l4.62,-4.62l-2.5,-2.5L12,18z" />
</vector> </vector>

View File

@ -4,6 +4,6 @@
android:viewportWidth="24.0" android:viewportWidth="24.0"
android:viewportHeight="24.0"> android:viewportHeight="24.0">
<path <path
android:fillColor="?attr/colorAccent" android:fillColor="?attr/colorControlNormal"
android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z" /> android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z" />
</vector> </vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="?attr/colorAccent"
android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z" />
</vector>

View File

@ -4,6 +4,6 @@
android:viewportWidth="24.0" android:viewportWidth="24.0"
android:viewportHeight="24.0"> android:viewportHeight="24.0">
<path <path
android:fillColor="?attr/colorAccent" android:fillColor="?attr/colorControlNormal"
android:pathData="M14,2H6C4.9,2 4.01,2.9 4.01,4L4,20c0,1.1 0.89,2 1.99,2H18c1.1,0 2,-0.9 2,-2V8L14,2zM10.94,18L7.4,14.46l1.41,-1.41l2.12,2.12l4.24,-4.24l1.41,1.41L10.94,18zM13,9V3.5L18.5,9H13z" /> android:pathData="M14,2H6C4.9,2 4.01,2.9 4.01,4L4,20c0,1.1 0.89,2 1.99,2H18c1.1,0 2,-0.9 2,-2V8L14,2zM10.94,18L7.4,14.46l1.41,-1.41l2.12,2.12l4.24,-4.24l1.41,1.41L10.94,18zM13,9V3.5L18.5,9H13z" />
</vector> </vector>

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Some files were not shown because too many files have changed in this diff Show More