Commit dec0a712 authored by 宋永孟's avatar 宋永孟

add commmonLib

parent 46327ade
/build
\ No newline at end of file
plugins {
id 'com.android.library'
id 'kotlin-android'
id 'kotlin-android-extensions'
id 'kotlin-kapt'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.2"
publishNonDefault true
defaultConfig {
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
javaCompileOptions {
annotationProcessorOptions {
arguments = [ setAttributeClassName : 'YdSubwaySetAttributeMethodProvider',
bindingDataClassName : 'YdSubwayBindingDataMethodProvider']
}
}
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
debug {
buildConfigField "boolean", "ENV_DEBUG", "true"
}
release {
buildConfigField "boolean", "ENV_DEBUG", "false"
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
androidExtensions{
experimental = true
}
viewBinding{
enabled = true
}
kapt{
generateStubs = true
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation rootProject.ext.dependencies.publicImplementation
testImplementation rootProject.ext.dependencies.testImplementation
androidTestImplementation rootProject.ext.dependencies.androidTestImplementation
kapt 'com.yidian.chameleon:annotationcompiler:0.3.29'
implementation 'com.yidian.chameleon:annotation:0.3.29'
api deps.yac.core
api deps.xarc.xbrid
api "com.yidian.xarc:xevent:0.0.3"
// api project(':flutter')
api "com.yidian.xpage:xpagenative:0.0.1"
}
\ No newline at end of file
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
\ No newline at end of file
package com.yidian.common
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.yidian.common.test", appContext.packageName)
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yidian.common">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application>
<activity android:name=".activity.OneKeyLoginActivity"/>
<activity android:name=".activity.LoginActivity" />
</application>
</manifest>
package com.yidian.common
class WebConfig {
companion object{
const val ADD_COMMENT: String = "addComment"
const val GET_GIF_DATA: String = "getGifData"
const val GO_TO_COMMENT_DETAIL: String = "gotoCommentDetail"
const val REPLY_DETAIL_COMMENT: String = "replyDetailComment"
const val UPDATE_LIKE: String = "updateLike"
const val GET_DOCID: String = "getDocId"
const val WEB_URL: String = "http://10.60.100.23:3100/"
}
}
\ No newline at end of file
package com.yidian.common
class AppConfig {
companion object{
const val WeChatAppKey = "wxef4c37f254e29e84"
const val WeChatAppSecret = "fb596ed3641b481b6f973774987fd04f"
const val QQAppKey = "101923771"
const val QQAppSecret = "c34d63cfcf9f8b13a71f48424b48d692"
const val SinaAppKey = "4157874278"
const val SinaAppSecret = "85c422bc0a1e0553e6a6a075701422a7"
const val SinaCallBackUrl = "https://api.weibo.com/oauth2/default.html"
const val FileProvider = "com.yidian.subway.provider"
const val appid = "metro"
const val cv = "1.0.0.7"
const val version = "000100"
const val distribution = "official"
const val platform = "1"
const val privacyPolicyStatement = "http://www.yidianzixun.com/landing_privacy?yidian_fs=2"
const val userProtocol = "http://www.yidianzixun.com/landing_agreement?yidian_fs=2"
//推送相关
const val UMAppKey = "5fe3fcc8d1c1ad39854efb90"
const val UMChannel = "ANDROID_CHANNEL"
const val UMType = "metro"
const val UMSecret = "8bb06c17a90d727c26bdd95b0e27a436"
const val PUSH_XIAOMI_SUPPORT_MASK = 0x40000000
const val PUSH_UMENG_SUPPORT_MASK = 0x20000000
const val PUSH_GETUI_SUPPORT_MASK = 0x10000000
const val PUSH_PASS_THROGH_UNIQUE_MASK = 0x00000001
const val ZIXUN_PUSH_LEVEL = PUSH_XIAOMI_SUPPORT_MASK
const val PUSH_LEVEL = (PUSH_XIAOMI_SUPPORT_MASK or PUSH_UMENG_SUPPORT_MASK
or PUSH_GETUI_SUPPORT_MASK or PUSH_PASS_THROGH_UNIQUE_MASK)
}
}
\ No newline at end of file
package com.yidian.common
class Constants {
companion object{
const val ITEM_TYPE_CHAMELEON = -1
const val CHAMELEON_ID = "chameleon_id"
const val CHAMELEON_D_TYPE = "dtype"
}
}
\ No newline at end of file
package com.yidian.common
class HawkConfig {
companion object{
const val GuestAccountUsername = "guestAccountUsername"
const val LoginStatus = "loginStatus"
const val Cookie = "cookie"
const val UmToken = "UmToken"
const val HeadViewHeight = "headViewHeight"
const val KeyboardHeight = "keyboardHeight"
const val YDEncryptionToken = "YDEncryptionToken"
const val SearchHistory = "searchHistory"
const val ProtocolIsAgree = "protocolIsAgree"
const val ChameleonDebugRemote = "ChameleonDebugRemote"
const val Username = "username"
const val Nickname = "nickname"
const val ProfileUrl = "profileUrl"
const val GifData = "gifData"
}
}
\ No newline at end of file
package com.yidian.common
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
@Parcelize
class ParcelizeMap(var map: Map<String, String?>?): Parcelable
\ No newline at end of file
package com.yidian.common
class XEventConfig {
companion object{
const val OPEN_GALLERY = "openGallery"
const val OPEN_PUSH = "openPush"
const val UPDATE_FLUTTER_PUSH_STATUS = "updateFlutterPushStatus"
const val SCROLL_SETTING_BAR = "scrollSettingBar"
const val BAR_SUBSCRIBE_STATUS = "updateBarSubscribeStatus"
const val SCROLL_SETTING_BOTTOM_BAR_STATUS = "scrollSettingBottomBarStatus"
const val REPLY_COMMENT: String = "replyComment"
const val GO_TO_COMMENT_DETAIL: String = "gotoCommentDetail"
const val REPLY_DETAIL_COMMENT: String = "replyDetailComment"
const val UPDATE_COMMENT: String = "updateComment"
const val UPDATE_LIKE: String = "updateLike"
const val GIF_DATA: String = "gifData"
}
}
\ No newline at end of file
package com.yidian.common
class XRouterPathConstants {
companion object {
const val ParamsKey = "ParamsMap"
const val FLASH = "/flash"
const val LOGIN = "/loginPhone"
const val ONE_KEY_LOGIN = "/common/oneKeyLogin"
const val LOGIN_NATIVE = "/loginNative"
const val USER_INFO = "/fragment/userInfo"
const val NEWS_MAIN = "/MainActivity"
const val NEWS_CONTENT = "/news"
const val GALLERY = "/imageGallery"
const val PROTOCOL = "/protocol"
const val SUPPORT = "/productSupport"
const val AUTHOR_HOME_PAGE = "/authorhome"
const val BROWSING_HISTORY = "/mine/BrowsingHistoryActivity"
const val COLLECTION = "/favorites"
const val SUBSCRIPTION = "/subscribe"
const val SEARCH_CHANNEL = "/newscontent/SearchChannelActivity"
const val SEARCH_RESULT = "/newscontent/SearchResultPageActivity"
const val AUDIO_DETAIL = "/newscontent/AudioDetailActivity"
const val VIDEO_COMMENT_DETAIL = "/newscontent/VideoDetailActivity"
const val COMMENT_TEST = "/newscontent/CommentTestActivity"
const val MINE = "/mine"
}
}
\ No newline at end of file
package com.yidian.common
import android.app.Activity
import android.app.Application
open class YdBaseApplication: Application(){
companion object{
lateinit var context: Application
var activityList = ArrayList<Activity>()
}
}
\ No newline at end of file
package com.yidian.common.activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.util.Log
import com.orhanobut.hawk.Hawk
import com.umeng.socialize.UMAuthListener
import com.umeng.socialize.UMShareAPI
import com.umeng.socialize.UMShareConfig
import com.umeng.socialize.bean.SHARE_MEDIA
import com.yidian.common.HawkConfig
import com.yidian.common.XRouterPathConstants
import com.yidian.common.base.BaseActivity
import com.yidian.common.databinding.ActivityLoginBinding
import com.yidian.common.http.HttpResult
import com.yidian.common.http.httpbean.IApiCallback
import com.yidian.common.http.httpbean.LoginBean
import com.yidian.xpage.XPageViewProtocol
import kotlinx.android.synthetic.main.activity_login.*
class LoginActivity : BaseActivity<ActivityLoginBinding>(), XPageViewProtocol, IApiCallback {
override fun createViewBinding(): ActivityLoginBinding {
return ActivityLoginBinding.inflate(layoutInflater)
}
override fun getXPageName(): String {
return XRouterPathConstants.LOGIN_NATIVE
}
override fun init(savedInstanceState: Bundle?) {
super.init(savedInstanceState)
setClickListener()
}
private fun setClickListener(){
lly_wechat.setOnClickListener{
loginByUmeng(SHARE_MEDIA.WEIXIN)
}
lly_qq.setOnClickListener{
loginByUmeng(SHARE_MEDIA.QQ)
}
lly_sina.setOnClickListener{
loginByUmeng(SHARE_MEDIA.SINA)
}
}
private fun loginByUmeng(platform: SHARE_MEDIA){
val config = UMShareConfig()
config.isNeedAuthOnGetUserInfo(true)
val mShareAPI = UMShareAPI.get(this@LoginActivity)
mShareAPI.setShareConfig(config)
mShareAPI.getPlatformInfo(this@LoginActivity, platform, object : UMAuthListener {
override fun onStart(platform: SHARE_MEDIA?) {
}
override fun onComplete(platform: SHARE_MEDIA?, action: Int, data: MutableMap<String, String>) {
val uid = data["uid"]
val name = data["name"]
val gender = data["gender"]
val iconurl = data["iconurl"]
Log.e("zhb-yd", "登录成功:uid->$uid,name->$name,gender->$gender,iconurl->$iconurl")
Hawk.put(HawkConfig.LoginStatus, true)
setResult(1, intent.putExtra("token", uid))
finish()
}
override fun onError(platform: SHARE_MEDIA?, action: Int, t: Throwable) {
Log.e("zhb-yd", "登录失败:" + t.message)
}
override fun onCancel(platform: SHARE_MEDIA?, action: Int) {
Log.e("zhb-yd", "登录取消")
}
})
}
override fun loginCallBack(t: HttpResult<LoginBean.Response?>?) {
Hawk.put(HawkConfig.LoginStatus, true)
val token = t?.result?.token
setResult(1, intent.putExtra("token", token))
finish()
}
override val context: Context
get() = this@LoginActivity
override fun showLoading(message: String?) {
TODO("Not yet implemented")
}
override fun showLoading() {
TODO("Not yet implemented")
}
override fun dismissLoading() {
TODO("Not yet implemented")
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
UMShareAPI.get(this).onActivityResult(requestCode, resultCode, data)
}
}
\ No newline at end of file
package com.yidian.common.activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.util.Log
import cn.jiguang.verifysdk.api.JVerificationInterface
import com.orhanobut.hawk.Hawk
import com.yidian.common.HawkConfig
import com.yidian.common.XRouterPathConstants
import com.yidian.common.base.BaseActivity
import com.yidian.common.databinding.ActivityOneKeyLoginBinding
import com.yidian.common.http.HttpResult
import com.yidian.common.http.httpbean.IApiCallback
import com.yidian.common.http.httpbean.LoginBean
import com.yidian.utils.ToastUtil
import com.yidian.xpage.XPageViewProtocol
import kotlinx.android.synthetic.main.activity_one_key_login.*
class OneKeyLoginActivity: BaseActivity<ActivityOneKeyLoginBinding>(), XPageViewProtocol, IApiCallback {
private lateinit var token: String
private lateinit var operator: String
override fun createViewBinding(): ActivityOneKeyLoginBinding {
return ActivityOneKeyLoginBinding.inflate(layoutInflater)
}
override fun init(savedInstanceState: Bundle?) {
super.init(savedInstanceState)
initJVerification()
setClickListener()
}
override fun getXPageName(): String {
return XRouterPathConstants.ONE_KEY_LOGIN
}
private fun initJVerification(){
JVerificationInterface.getToken(this, 5000) { code, content, operator ->
if(code == 2000){
this.token = content
this.operator = operator
Log.e("zhb-yd", "token=$content, operator=$operator")
}else{
Log.e("zhb-yd", "code=$code, message=$content")
}
}
}
private fun setClickListener(){
btn_oneKeyLogin.setOnClickListener{
ToastUtil.showToast(this, "极光一键登录")
Hawk.put(HawkConfig.LoginStatus, true)
setResult(1, intent.putExtra("token", token))
finish()
}
tv_login.setOnClickListener{
startActivityForResult(Intent(this, LoginActivity::class.java),0)
}
}
override fun loginCallBack(t: HttpResult<LoginBean.Response?>?) {
TODO("Not yet implemented")
}
override val context: Context
get() = this@OneKeyLoginActivity
override fun showLoading(message: String?) {
TODO("Not yet implemented")
}
override fun showLoading() {
TODO("Not yet implemented")
}
override fun dismissLoading() {
TODO("Not yet implemented")
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if(resultCode == 1){
setResult(resultCode, data)
finish()
}
}
}
\ No newline at end of file
package com.yidian.common.base
import android.os.Bundle
import android.view.View
import androidx.viewbinding.ViewBinding
import com.yidian.common.R
import com.yidian.news.ui.SystemBarUtils
import com.yidian.nightmode.base.NightAppCompatActivity
import com.yidian.nightmode.preference.NightModeConfig
import com.yidian.xpage.XPageViewProtocol
abstract class BaseActivity<VB :ViewBinding> : NightAppCompatActivity(), XPageViewProtocol {
protected lateinit var viewBind:VB
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewBind = createViewBinding()
extraViewBinding()
setContentView(viewBind.root)
init(savedInstanceState)
}
/**
* 如果有多个viewBinding需要初始化时
*/
open fun extraViewBinding() {
}
override fun updateCover(isNight: Boolean) {}
override fun getCurrentTheme(isNight: Boolean): Int {
return if (isNight) R.style.subway_theme_night else R.style.subway_theme_day
}
override fun setContentView(view:View){
SystemBarUtils.setStatusBarTransparent(this.window)
if (allowChangeStatusBarTextColor() ) {
setStatusBarTextColor(NightModeConfig.getInstance().nightMode)
}
super.setContentView(view)
}
private fun allowChangeStatusBarTextColor(): Boolean {
return SystemBarUtils.supportTranslucentStatusBar() && SystemBarUtils.supportChangeStatusBarTextColor()
}
abstract fun createViewBinding(): VB
override fun onNightModeChanged(isNight: Boolean) {
super.onNightModeChanged(isNight)
if (allowChangeStatusBarTextColor()) {
setStatusBarTextColor(isNight)
}
}
open fun setStatusBarTextColor(isNight: Boolean) {
if (isNight) {
if (this.useWhiteStatusBarTextColorInNightMode()) {
SystemBarUtils.setStatusBarTextColorWhite(this)
} else {
SystemBarUtils.setStatusBarTextColorBlack(this)
}
} else if (this.useBlackStatusBarTextColorInDayMode()) {
SystemBarUtils.setStatusBarTextColorBlack(this)
} else {
SystemBarUtils.setStatusBarTextColorWhite(this)
}
}
private fun useBlackStatusBarTextColorInDayMode(): Boolean {
return true
}
private fun useWhiteStatusBarTextColorInNightMode(): Boolean {
return true
}
protected open fun init(savedInstanceState: Bundle?) {}
}
\ No newline at end of file
package com.yidian.common.base
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.OnLifecycleEvent
import java.lang.ref.WeakReference
abstract class BaseActivityRepository<V : IBaseView>(view:V):IRepository {
private var viewReference:WeakReference<out IBaseView> = WeakReference(view)
init {
view.lifecycle.addObserver(this)
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun onResume(){}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun onPause(){}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy(){
viewReference.get()?.lifecycle?.removeObserver(this)
}
}
\ No newline at end of file
package com.yidian.common.base
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.viewbinding.ViewBinding
import com.yidian.commoncomponent.BaseFragment
/**
* 所有Fragment的基类
*/
abstract class BaseFragment<VB : ViewBinding> : BaseFragment() {
private var _binding: VB?=null
protected val viewBinding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = createViewBinding(inflater,container)
return _binding!!.root
}
abstract fun createViewBinding(inflater: LayoutInflater, container: ViewGroup?): VB
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
init(savedInstanceState)
}
protected open fun init(savedInstanceState: Bundle?) {}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
fun showToast(msg:String){
Toast.makeText(requireContext(),msg,Toast.LENGTH_SHORT).show()
}
}
package com.yidian.common.base
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.OnLifecycleEvent
import java.lang.ref.WeakReference
abstract class BaseFragmentRepository<V : IBaseView>(view:V):IRepository{
protected val viewReference:WeakReference<V> = WeakReference(view)
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun onResume(){}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun onPause(){}
}
\ No newline at end of file
package com.yidian.common.base
import android.os.Bundle
import androidx.viewbinding.ViewBinding
abstract class BaseRepositoryFragment<R : BaseActivityRepository<out IBaseView>,VB :ViewBinding> :BaseFragment<VB>() {
protected val repository :R = createRepository()
abstract fun createRepository(): R
/**
* 此处为了处理Fragment复用后ARepository的生命周期丢失问题
*/
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycle.addObserver(repository)
}
override fun onDestroy() {
super.onDestroy()
lifecycle.removeObserver(repository)
}
}
\ No newline at end of file
package com.yidian.common.base
import androidx.lifecycle.LifecycleOwner
interface IBaseView :LifecycleOwner{
}
\ No newline at end of file
package com.yidian.common.base
import androidx.lifecycle.LifecycleObserver
interface IRepository: LifecycleObserver
\ No newline at end of file
package com.yidian.common.cardutils
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.yidian.chameleon.ChameleonParser
import org.json.JSONObject
class CardFactory {
companion object{
fun createChameleonCard(parent: ViewGroup, cardType: Int, chameleonViewUtils: ChameleonViewUtils, bean: JSONObject): View{
val chameleonParser = ChameleonParser(parent.context)
val chameleonView: View = chameleonViewUtils.createChameleonView(cardType, chameleonParser)
chameleonParser.bindTemplateData(chameleonView, bean)
return chameleonView
}
fun createViewHolder(parent: ViewGroup, cardType: Int, chameleonViewUtils: ChameleonViewUtils): RecyclerView.ViewHolder {
return ChameleonCard(parent, cardType, chameleonViewUtils).getYdViewHolder()
}
}
}
\ No newline at end of file
package com.yidian.common.cardutils
import android.view.View
import android.view.ViewGroup
import com.yidian.chameleon.ChameleonParser
import com.yidian.common.cardutils.bean.CommonCardBean
import org.json.JSONObject
class ChameleonCard(parent: ViewGroup, cardType: Int, chameleonViewUtils: ChameleonViewUtils): CommonCard() {
private val chameleonParser = ChameleonParser(parent.context)
private val chameleonView: View = chameleonViewUtils.createChameleonView(cardType, chameleonParser)
init {
setCardView(chameleonView)
setClickListener()
}
override fun setData(bean: Any) {
bean as CommonCardBean
chameleonParser.bindTemplateData(chameleonView, JSONObject(bean.content as Map<*, *>))
}
private fun setClickListener() {
}
}
\ No newline at end of file
package com.yidian.common.cardutils
import android.content.Context
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.widget.TextView
import androidx.core.view.updateLayoutParams
import androidx.recyclerview.widget.RecyclerView
import com.yidian.chameleon.ChameleonParser
import com.yidian.common.R
import com.yidian.common.YdBaseApplication.Companion.context
class ChameleonViewUtils(context: Context) {
var chameleonParser: ChameleonParser = ChameleonParser(context)
fun createChameleonView(chameleonId: Int, chameleonParser: ChameleonParser = this.chameleonParser): View {
if (chameleonId == 800001) {
val params = RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT,200)
return TextView(context).apply {
text = "测试数据 80001"
textSize = 17f
gravity = Gravity.CENTER
layoutParams = params
}
} else {
return chameleonParser.createView(chameleonId.toString())
}
}
}
\ No newline at end of file
package com.yidian.common.cardutils
import android.view.View
abstract class CommonCard: IHolderData {
private lateinit var viewHolder: YdViewHolder
private lateinit var cardView: View
fun setCardView(cardView: View){
this.cardView = cardView
viewHolder = YdViewHolder(cardView, this)
}
fun getCardView(): View{
return cardView
}
fun getYdViewHolder(): YdViewHolder{
return viewHolder
}
}
\ No newline at end of file
package com.yidian.common.cardutils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.yidian.common.R
import com.yidian.common.XRouterPathConstants
import com.yidian.common.cardutils.bean.PolymerCommonCardBean
import com.yidian.common.services.XEventService
import com.yidian.nightmode.widget.YdCheckedBox
import com.yidian.nightmode.widget.YdImageView
import com.yidian.xarc.xevent.XBaseEvent
import com.yidian.xpage.XPageManager
class CommonDailyCard(val parent: ViewGroup): CommonCard() {
private val rootView: View = LayoutInflater.from(parent.context).inflate(R.layout.item_common_daily_card, parent, false)
private val cbChecked = rootView.findViewById<YdCheckedBox>(R.id.cb_checked)
private val ivClose = rootView.findViewById<YdImageView>(R.id.iv_close)
private lateinit var polymerCommonCardBean: PolymerCommonCardBean
init {
setCardView(rootView)
setClickListener()
}
override fun setData(bean: Any) {
bean as PolymerCommonCardBean
polymerCommonCardBean = bean
if(polymerCommonCardBean.isShowChecked){
cbChecked.visibility = View.VISIBLE
cbChecked.isChecked = polymerCommonCardBean.isChecked
}else{
cbChecked.visibility = View.GONE
}
}
private fun setClickListener(){
rootView.setOnClickListener{
XPageManager.push(XRouterPathConstants.AUTHOR_HOME_PAGE, null)
}
ivClose.setOnClickListener {
val xBaseEvent = XBaseEvent("feedback", "CommonDailyCard")
XEventService.postEvent(xBaseEvent)
}
cbChecked.setOnClickListener {
polymerCommonCardBean.isChecked = cbChecked.isChecked
}
}
}
\ No newline at end of file
package com.yidian.common.cardutils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.yidian.common.R
import com.yidian.nightmode.widget.YdLinearLayout
import com.yidian.nightmode.widget.YdRelativeLayout
class DailyHeadCard(parent: ViewGroup): CommonCard() {
private val rootView: View = LayoutInflater.from(parent.context).inflate(R.layout.item_daily_head_card, parent, false)
private val rlyNewsBroadcast = rootView.findViewById<YdRelativeLayout>(R.id.rly_newsBroadcast)
private val llySubscribe = rootView.findViewById<YdLinearLayout>(R.id.lly_subscribe)
init {
setCardView(rootView)
setClickListener()
}
override fun setData(bean: Any) {
}
private fun setClickListener(){
rlyNewsBroadcast.setOnClickListener {
}
llySubscribe.setOnClickListener {
}
}
}
\ No newline at end of file
package com.yidian.common.cardutils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import com.yidian.common.R
import com.yidian.common.cardutils.adapter.FlashAdapter
import com.yidian.common.cardutils.bean.PolymerCommonCardBean
import com.yidian.nightmode.widget.YdRecyclerView
class FlashHeadCard(var parent: ViewGroup): CommonCard() {
private val rootView: View = LayoutInflater.from(parent.context).inflate(R.layout.item_flash_head_card, parent, false)
private val rvHead = rootView.findViewById<YdRecyclerView>(R.id.rv_head)
val adapter: FlashAdapter by lazy { FlashAdapter(parent.context) }
init {
initView()
setCardView(rootView)
}
private fun initView(){
val layoutManager = LinearLayoutManager(parent.context)
layoutManager.orientation = LinearLayoutManager.HORIZONTAL
rvHead.layoutManager = layoutManager
rvHead.adapter = adapter
}
override fun setData(bean: Any) {
bean as PolymerCommonCardBean
// adapter.update(bean.flashHeadBeanList)
}
}
\ No newline at end of file
package com.yidian.common.cardutils
interface IHolderData {
fun setData(bean: Any)
}
\ No newline at end of file
package com.yidian.common.cardutils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.yidian.common.R
class LoadNoMoreCard(val parent: ViewGroup): CommonCard() {
private val rootView: View = LayoutInflater.from(parent.context).inflate(R.layout.item_load_no_more, parent, false)
init {
setCardView(rootView)
}
override fun setData(bean: Any) {
}
}
package com.yidian.common.cardutils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.yidian.common.R
import com.yidian.common.XRouterPathConstants
import com.yidian.common.cardutils.bean.PolymerCommonCardBean
import com.yidian.nightmode.widget.YdCheckedBox
import com.yidian.xpage.XPageManager
class PodcastDailyCard(parent: ViewGroup): CommonCard() {
private val rootView: View = LayoutInflater.from(parent.context).inflate(R.layout.item_podcast_daily_card, parent, false)
private val cbChecked = rootView.findViewById<YdCheckedBox>(R.id.cb_checked)
private val tvHomeName = rootView.findViewById<TextView>(R.id.tv_itemHomeName)
private val tvHomeContent = rootView.findViewById<TextView>(R.id.tv_itemHomeContent)
private lateinit var polymerCommonCardBean: PolymerCommonCardBean
init {
setCardView(rootView)
setClickListener()
}
override fun setData(bean: Any) {
bean as PolymerCommonCardBean
polymerCommonCardBean = bean
if(polymerCommonCardBean.isShowChecked){
cbChecked.visibility = View.VISIBLE
cbChecked.isChecked = polymerCommonCardBean.isChecked
}else{
cbChecked.visibility = View.GONE
}
// tvHomeName.text = polymerCommonCardBean.name
// tvHomeContent.text = polymerCommonCardBean.content
}
private fun setClickListener(){
rootView.setOnClickListener{
XPageManager.push(XRouterPathConstants.NEWS_CONTENT, null)
}
cbChecked.setOnClickListener {
polymerCommonCardBean.isChecked = cbChecked.isChecked
}
}
}
\ No newline at end of file
package com.yidian.common.cardutils
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
class PolymerCardFactory {
companion object{
const val LoadNoMoreCard = -200 //加载更多无数据卡
const val SubscribeHead = 902 //订阅头部卡
const val SubscribeHeadNull = 903 //无订阅头部卡
const val CommonPolymerCard = 100 //普通聚合卡
fun createViewHolder(parent: ViewGroup, cardType: Int, chameleonViewUtils: ChameleonViewUtils): RecyclerView.ViewHolder {
return when(cardType){
LoadNoMoreCard -> LoadNoMoreCard(parent).getYdViewHolder()
SubscribeHead -> SubscribeHeadCard(parent).getYdViewHolder()
SubscribeHeadNull -> SubscribeHeadTextCard(parent, chameleonViewUtils).getYdViewHolder()
else -> PolymerNormalCard(parent, chameleonViewUtils).getYdViewHolder()
}
}
}
}
\ No newline at end of file
package com.yidian.common.cardutils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import com.yidian.common.R
import com.yidian.common.cardutils.adapter.CommonAdapter
import com.yidian.common.cardutils.bean.PolymerCommonCardBean
import com.yidian.common.widget.YdMaxRecyclerView
import com.yidian.nightmode.widget.YdCheckedBox
import com.yidian.nightmode.widget.YdFrameLayout
import com.yidian.nightmode.widget.YdView
import org.json.JSONObject
class PolymerNormalCard(var parent: ViewGroup, var chameleonViewUtils: ChameleonViewUtils): CommonCard() {
private val rootView: View = LayoutInflater.from(parent.context).inflate(R.layout.item_polymer_chameleon_card, parent, false)
private val headerParent = rootView.findViewById<YdFrameLayout>(R.id.fly_header)
private val rvCard = rootView.findViewById<YdMaxRecyclerView>(R.id.rv_card)
private val cbChecked = rootView.findViewById<YdCheckedBox>(R.id.cb_checked)
private val vManage = rootView.findViewById<YdView>(R.id.v_manage)
private val cardAdapter = CommonAdapter(chameleonViewUtils)
private lateinit var polymerCommonCardBean: PolymerCommonCardBean
init {
setCardView(rootView)
initRecyclerView()
setClickListener()
}
private fun initRecyclerView(){
rvCard.layoutManager = LinearLayoutManager(parent.context)
rvCard.adapter = cardAdapter
rvCard.isNestedScrollingEnabled = false
}
override fun setData(bean: Any) {
polymerCommonCardBean = bean as PolymerCommonCardBean
if(polymerCommonCardBean.isShowChecked){
cbChecked.visibility = View.VISIBLE
vManage.visibility = View.VISIBLE
}else{
cbChecked.visibility = View.GONE
vManage.visibility = View.GONE
}
cbChecked.isChecked = polymerCommonCardBean.isChecked
val header = bean.header
if(header != null){
val headerView = CardFactory.createChameleonCard(headerParent, header.card_type_id, chameleonViewUtils, JSONObject(header.content as Map<*, *>))
headerParent.removeAllViews()
headerParent.addView(headerView)
}else{
headerParent.removeAllViews()
}
val cardList = bean.card_list
if(cardList != null){
cardAdapter.update(cardList)
}
}
private fun setClickListener() {
vManage.setOnClickListener {
cbChecked.isChecked = !cbChecked.isChecked
polymerCommonCardBean.isChecked = cbChecked.isChecked
}
}
}
\ No newline at end of file
package com.yidian.common.cardutils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.yidian.common.R
import com.yidian.common.XRouterPathConstants
import com.yidian.common.YdBaseApplication
import com.yidian.common.cardutils.adapter.OnItemClickListener
import com.yidian.common.cardutils.adapter.SubscribeAdapter
import com.yidian.common.cardutils.bean.CommonCardBean
import com.yidian.common.cardutils.bean.PolymerCommonCardBean
import com.yidian.common.cardutils.bean.SubscribeHeadBean
import com.yidian.nightmode.widget.YdRecyclerView
import com.yidian.utils.ToastUtil
import com.yidian.xpage.XPageManager
import org.json.JSONArray
class SubscribeHeadCard(val parent: ViewGroup): CommonCard() {
private val rootView: View = LayoutInflater.from(parent.context).inflate(R.layout.item_subscribe_head_card, parent, false)
private val rvSubscribe = rootView.findViewById<YdRecyclerView>(R.id.rv_subscribe)
val adapter: SubscribeAdapter by lazy { SubscribeAdapter(parent.context) }
private val subscribeHeadBeanList: ArrayList<SubscribeHeadBean> by lazy { ArrayList<SubscribeHeadBean>() }
private var lastClickTime = 0L
init {
initView()
setCardView(rootView)
setClickListener()
}
private fun initView(){
val layoutManager = LinearLayoutManager(parent.context)
layoutManager.orientation = LinearLayoutManager.HORIZONTAL
rvSubscribe.layoutManager = layoutManager
rvSubscribe.adapter = adapter
}
override fun setData(bean: Any) {
bean as PolymerCommonCardBean
val commonCardBean = bean.card_list?.get(0)
subscribeHeadBeanList.clear()
subscribeHeadBeanList.add(SubscribeHeadBean("nativeAdd", "添加", null).setViewType(SubscribeAdapter.headType))
val gson = Gson()
val beanJson = gson.toJson(commonCardBean?.content)
val headerResultList = gson.fromJson<ArrayList<SubscribeHeadBean>>(beanJson, object: TypeToken<ArrayList<SubscribeHeadBean>>(){}.type)
subscribeHeadBeanList.addAll(headerResultList)
subscribeHeadBeanList.add(SubscribeHeadBean("nativeAll", "全部", null).setViewType(SubscribeAdapter.footerType))
adapter.update(subscribeHeadBeanList)
}
private fun setClickListener(){
adapter.setOnItemClickListener(object : OnItemClickListener<SubscribeHeadBean> {
override fun onClick(view: View?, position: Int, item: SubscribeHeadBean?) {
val currentClickTime = System.currentTimeMillis()
if(currentClickTime - lastClickTime < 1000) return
lastClickTime = currentClickTime
item?.let {
when (item.wm_id) {
"nativeAdd" -> ToastUtil.showToast(YdBaseApplication.context, "该功能暂未开放")
"nativeAll" -> {
XPageManager.push(XRouterPathConstants.SUBSCRIPTION, null)
}
else -> {
val paramsMap = hashMapOf<String, Any>(Pair("fromId", item.wm_id!!))
XPageManager.push(XRouterPathConstants.AUTHOR_HOME_PAGE, paramsMap)
}
}
}
}
})
}
}
package com.yidian.common.cardutils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.yidian.common.R
import com.yidian.common.cardutils.adapter.OnItemClickListener
import com.yidian.common.cardutils.adapter.SubscribeAdapter
import com.yidian.common.cardutils.bean.CommonCardBean
import com.yidian.common.cardutils.bean.PolymerCommonCardBean
import com.yidian.common.cardutils.bean.SubscribeHeadBean
import com.yidian.nightmode.widget.YdFrameLayout
import com.yidian.nightmode.widget.YdRecyclerView
import com.yidian.utils.ToastUtil
import org.json.JSONArray
import org.json.JSONObject
class SubscribeHeadTextCard(val parent: ViewGroup, var chameleonViewUtils: ChameleonViewUtils): CommonCard() {
private val rootView: View = LayoutInflater.from(parent.context).inflate(R.layout.item_subscribe_head_text_card, parent, false)
private val flyRoot = rootView.findViewById<YdFrameLayout>(R.id.fly_root)
init {
setCardView(rootView)
}
override fun setData(bean: Any) {
bean as PolymerCommonCardBean
val commonCardBean = bean.card_list?.get(0)
val cardType = commonCardBean?.card_type_id
if(cardType != null){
val cardView = CardFactory.createChameleonCard(flyRoot, cardType, chameleonViewUtils, JSONObject(commonCardBean.content as Map<*, *>))
flyRoot.addView(cardView)
}
}
}
package com.yidian.common.cardutils
import android.view.View
import androidx.recyclerview.widget.RecyclerView
class YdViewHolder(itemView: View, var holderData: IHolderData): RecyclerView.ViewHolder(itemView){
fun setData(data: Any){
holderData.setData(data)
}
}
\ No newline at end of file
package com.yidian.common.cardutils.adapter
import android.util.Log
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.yidian.common.cardutils.CardFactory
import com.yidian.common.cardutils.ChameleonViewUtils
import com.yidian.common.cardutils.YdViewHolder
import com.yidian.common.cardutils.bean.CommonCardBean
class CommonAdapter(var chameleonViewUtils: ChameleonViewUtils): RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val dataList: ArrayList<CommonCardBean> by lazy { ArrayList<CommonCardBean>() }
override fun getItemCount(): Int {
return dataList.size
}
override fun getItemViewType(position: Int): Int {
return dataList[position].card_type_id
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return CardFactory.createViewHolder(parent, viewType, chameleonViewUtils)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
holder as YdViewHolder
holder.setData(dataList[position])
}
fun update(newData: ArrayList<CommonCardBean>){
newData.let {
dataList.clear()
dataList.addAll(it)
notifyDataSetChanged()
}
}
}
package com.yidian.common.cardutils.adapter
import android.annotation.SuppressLint
import android.content.Context
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.yidian.common.R
import com.yidian.common.YdBaseApplication.Companion.context
import com.yidian.common.cardutils.bean.FlashHeadBean
import com.yidian.common.utils.ViewHolderUtil.Companion.createItemView
import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.item_flash_head.*
class FlashAdapter(var context: Context): RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val dataList: ArrayList<FlashHeadBean> by lazy { ArrayList<FlashHeadBean>() }
private lateinit var mOnItemClickListener: OnItemClickListener<FlashHeadBean>
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return ViewHolder(createItemView(parent, R.layout.item_flash_head))
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
holder as ViewHolder
holder.setData(dataList[position])
holder.itemView.setOnClickListener{
mOnItemClickListener.onClick(it, position, dataList[position])
}
}
fun update(newData: ArrayList<FlashHeadBean>){
newData.let {
dataList.clear()
dataList.addAll(it)
notifyDataSetChanged()
}
}
override fun getItemCount(): Int {
return dataList.size
}
fun setOnItemClickListener(onItemClickListener: OnItemClickListener<FlashHeadBean>) {
mOnItemClickListener = onItemClickListener
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), LayoutContainer {
override val containerView: View
get() = itemView
@SuppressLint("ResourceAsColor")
fun setData(flashHeadBean: FlashHeadBean) {
tv_tab.text = flashHeadBean.tab
if(flashHeadBean.isChecked){
tv_tab.setTextColor(context.resources.getColor(R.color.secondTabSelectColor))
tv_tab.setBackgroundResource(R.drawable.bg_checked_radio)
}else{
tv_tab.setTextColor(context.resources.getColor(R.color.secondTabUnSelectColor))
tv_tab.setBackgroundResource(R.drawable.bg_unchecked_radio)
}
}
}
}
package com.yidian.common.cardutils.adapter
import android.view.View
import com.yidian.common.cardutils.bean.SubscribeHeadBean
interface OnItemClickListener<T> {
fun onClick(view: View?, position: Int, item: T?)
}
\ No newline at end of file
package com.yidian.common.cardutils.adapter
import android.content.Context
import android.util.Log
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.yidian.common.cardutils.ChameleonViewUtils
import com.yidian.common.cardutils.PolymerCardFactory
import com.yidian.common.cardutils.YdViewHolder
import com.yidian.common.cardutils.bean.PolymerCommonCardBean
class PolymerCardAdapter(context: Context): RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val dataList: ArrayList<PolymerCommonCardBean> by lazy { ArrayList<PolymerCommonCardBean>() }
private val chameleonViewUtils: ChameleonViewUtils = ChameleonViewUtils(context)
override fun getItemCount(): Int {
return dataList.size
}
override fun getItemViewType(position: Int): Int {
return dataList[position].aggregation_card_type_id
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return PolymerCardFactory.createViewHolder(parent, viewType, chameleonViewUtils)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
holder as YdViewHolder
holder.setData(dataList[position])
}
fun update(newData: ArrayList<PolymerCommonCardBean>){
newData.let {
dataList.clear()
dataList.addAll(it)
notifyDataSetChanged()
}
}
fun loadMore(newData: ArrayList<PolymerCommonCardBean>){
newData.let {
dataList.addAll(it)
notifyDataSetChanged()
}
}
fun clear(){
dataList.clear()
notifyDataSetChanged()
}
}
package com.yidian.common.cardutils.adapter
import android.annotation.SuppressLint
import android.content.Context
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.yidian.common.R
import com.yidian.common.cardutils.bean.SubscribeHeadBean
import com.yidian.common.utils.ViewHolderUtil.Companion.createItemView
import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.item_subscribe_head.*
class SubscribeAdapter(val context: Context): RecyclerView.Adapter<RecyclerView.ViewHolder>() {
companion object{
const val commonType = 0
const val headType = -1
const val footerType = -2
}
private val dataList: ArrayList<SubscribeHeadBean> by lazy { ArrayList<SubscribeHeadBean>() }
private lateinit var mOnItemClickListener: OnItemClickListener<SubscribeHeadBean>
override fun getItemViewType(position: Int): Int {
return dataList[position].getViewType()
}
override fun getItemCount(): Int {
return dataList.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return ViewHolder(context, createItemView(parent, R.layout.item_subscribe_head), viewType)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
holder as ViewHolder
holder.setData(dataList[position])
holder.itemView.setOnClickListener{
mOnItemClickListener.onClick(it, position, dataList[position])
}
}
fun update(newData: ArrayList<SubscribeHeadBean>){
newData.let {
dataList.clear()
dataList.addAll(it)
notifyDataSetChanged()
}
}
fun setOnItemClickListener(onItemClickListener: OnItemClickListener<SubscribeHeadBean>) {
mOnItemClickListener = onItemClickListener
}
class ViewHolder(val context: Context, itemView: View, private val viewType: Int) : RecyclerView.ViewHolder(itemView), LayoutContainer {
override val containerView: View
get() = itemView
@SuppressLint("ResourceAsColor")
fun setData(subscribeHeadBean: SubscribeHeadBean) {
tv_content.text = subscribeHeadBean.name
if(viewType == commonType){
iv_add.visibility = View.GONE
iv_more.visibility = View.GONE
iv_icon.visibility = View.VISIBLE
iv_point.visibility = View.VISIBLE
Glide.with(context).load(subscribeHeadBean.image).into(iv_icon)
}else{
iv_icon.visibility = View.GONE
iv_point.visibility = View.GONE
if(viewType == headType){
iv_add.visibility = View.VISIBLE
iv_more.visibility = View.GONE
}else if(viewType == footerType){
iv_more.visibility = View.VISIBLE
iv_add.visibility = View.GONE
}
}
}
}
}
package com.yidian.common.cardutils.bean
class CommonCardBean(
var flow_type_id: Int = 0,
var card_type_id: Int = 0,
var chameleon_id: String = "",
var content: Any
)
\ No newline at end of file
package com.yidian.common.cardutils.bean
class FlashHeadBean(var tabId: Int, var tab: String, var isChecked: Boolean)
\ No newline at end of file
package com.yidian.common.cardutils.bean
class PolymerCommonCardBean(var aggregation_card_type_id: Int, var header: CommonCardBean?, var card_list: ArrayList<CommonCardBean>?){
var isShowChecked: Boolean = false
var isChecked: Boolean = false
}
\ No newline at end of file
package com.yidian.common.cardutils.bean
import com.yidian.common.cardutils.adapter.SubscribeAdapter
class SubscribeHeadBean(var wm_id: String?, var name: String?, var image: String?){
private var viewType = SubscribeAdapter.commonType
fun setViewType(viewType: Int): SubscribeHeadBean{
this.viewType = viewType
return this
}
fun getViewType(): Int{
return this.viewType
}
}
\ No newline at end of file
package com.yidian.common.chameleon
import org.json.JSONObject
data class ChameleonEvent (
var module:String?,
var action:String?,
var params:JSONObject?,
var options:JSONObject?
)
\ No newline at end of file
package com.yidian.common.chameleon
interface ChameleonEventService {
fun dispatchEvent(event:ChameleonEvent)
}
\ No newline at end of file
package com.yidian.common.chameleon
object ChameleonServiceManager {
private val services:MutableSet<ChameleonEventService> = mutableSetOf()
fun registerChameleonService(service:ChameleonEventService){
services.add(service)
}
fun unregisterChameleonService(service:ChameleonEventService){
services.remove(service)
}
fun unregisterAllChameleonService(){
services.clear()
}
fun dispatchEvent(event:ChameleonEvent){
services.forEach{
it.dispatchEvent(event)
}
}
}
\ No newline at end of file
package com.yidian.common.chameleon
import com.yidian.chameleon.js.BridgeService
import com.yidian.chameleon.js.BridgeService.IAppDispatcher
import io.reactivex.Observable
import org.json.JSONObject
class ChameleonServiceRouter: IAppDispatcher {
override fun connectEventReceiver(eventReceiver: IAppDispatcher.IServiceEventReceiver?): String {
return ""
}
override fun dispatchCall(
module: String?,
action: String?,
params: JSONObject?,
options: JSONObject?
): Observable<BridgeService.JsResult> {
ChameleonServiceManager.dispatchEvent(ChameleonEvent(module,action,params,options))
val jsResult = BridgeService.JsResult(params)
return Observable.just(jsResult)
}
override fun disconnectEventReceiver(evToken: String?) {}
}
\ No newline at end of file
package com.yidian.common.http
import com.orhanobut.hawk.Hawk
import com.yidian.common.HawkConfig
import okhttp3.Interceptor
import okhttp3.Response
class ApiSaveCookiesInterceptor: Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val originalResponse = chain.proceed(chain.request())
val cookieList = originalResponse.headers("Set-Cookie")
if (cookieList.isNotEmpty()) {
for (cookie in cookieList) {
if(cookie.contains("JSESSIONID")){
Hawk.put(HawkConfig.Cookie, cookie)
}
}
}
return originalResponse
}
}
\ No newline at end of file
package com.yidian.common.http
import com.orhanobut.hawk.Hawk
import okhttp3.Interceptor
import okhttp3.Request
import okhttp3.Response
class ApiSetCookiesInterceptor: Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val builder: Request.Builder = chain.request().newBuilder()
val cookie: String? = Hawk.get("cookie", null)
if (cookie != null) {
builder.addHeader("Cookie", cookie)
}
return chain.proceed(builder.build())
}
}
\ No newline at end of file
package com.yidian.common.http
import com.yidian.common.AppConfig
import com.yidian.common.YdBaseApplication
import com.yidian.common.utils.EncryptUtil
import com.yidian.common.utils.NetWorkUtils
import com.yidian.yac.ftdevicefinger.core.FtDeviceFingerManager
class HttpParamsUtils{
companion object{
fun getParamsMap(): HashMap<String, String>{
val networkType = NetWorkUtils.getNetWorkType(YdBaseApplication.context)
val timeStamp = System.currentTimeMillis()
val queryParamsMap = HashMap<String, String>()
queryParamsMap["appid"] = AppConfig.appid
queryParamsMap["cv"] = AppConfig.cv
queryParamsMap["version"] = AppConfig.version
queryParamsMap["distribution"] = AppConfig.distribution
queryParamsMap["net_type"] = networkType
queryParamsMap["platform"] = AppConfig.platform
queryParamsMap["equipment_id"] = getEquipmentId()
queryParamsMap["request_id"] = getRequestId(timeStamp)
queryParamsMap["sign_string"] = getSignString(timeStamp)
return queryParamsMap
}
private fun getEquipmentId(): String{
var equipmentId = ""
val tempId = FtDeviceFingerManager.getEquipmentId()
if(tempId != null){
equipmentId = tempId
}
return equipmentId
}
private fun getRequestId(timeStamp: Long): String{
val sb = StringBuilder()
sb.append(AppConfig.appid)
sb.append('_')
sb.append(getEquipmentId())
sb.append('_')
sb.append(timeStamp)
return sb.toString()
}
private fun getSignString(timeStamp: Long): String{
val sb = StringBuilder()
sb.append(AppConfig.appid)
sb.append(AppConfig.platform)
sb.append(getEquipmentId())
sb.append(getRequestId(timeStamp))
sb.append("ydapp-metro")
val signMD5 = EncryptUtil.getMD5(sb.toString())
return if(signMD5.length > 8){
signMD5.substring(0, 8)
}else{
signMD5
}
}
}
}
\ No newline at end of file
package com.yidian.common.http
/**
* create by Administrator
* date 2019/2/12 0012
* desc
*/
class HttpResult<T> {
var code = 0
var status: String? = null
var reason: String? = null
var result: T? = null
}
\ No newline at end of file
package com.yidian.common.http
import android.annotation.SuppressLint
import android.app.Activity
import androidx.fragment.app.Fragment
import com.google.gson.JsonParseException
import com.yidian.common.YdBaseApplication
import com.yidian.utils.ToastUtil
import io.reactivex.rxjava3.core.Observer
import io.reactivex.rxjava3.disposables.Disposable
abstract class HttpResultSubscriber<T>(private var showProgress: Boolean = false) : Observer<HttpResult<T>?> {
private var isShowErrorMsg = true
override fun onSubscribe(d: Disposable) { //网络请求之前
if(showProgress){
}
}
override fun onComplete() { //网络请求完成
if(showProgress){
}
}
override fun onError(e: Throwable) {
if (e.toString().contains("ConnectException") || e.toString().contains("Unable to resolve host")) {
if (isShowErrorMsg) {
ToastUtil.showToast(YdBaseApplication.context, "当前网络链接不畅,请检查您的网络情况")
}
} else if ("connect timed out" == e.message) {
if (isShowErrorMsg) {
ToastUtil.showToast(YdBaseApplication.context, "服务器连接超时")
}
} else if (e is JsonParseException || e.toString().contains("Json") || e.toString().contains("Gson")) {
if (isShowErrorMsg) {
ToastUtil.showToast(YdBaseApplication.context, "数据解析异常")
}
} else {
if (isShowErrorMsg) {
ToastUtil.showToast(YdBaseApplication.context, "网络请求异常")
}
}
onRequestFailure(Exception(e.toString()))
}
override fun onNext(result: HttpResult<T>?) {
if (result?.code == 0) {
onRequestSuccess(result)
}else{
onFailer(result)
ToastUtil.showToast(YdBaseApplication.context, result?.reason)
}
}
abstract fun onSuccess(result: HttpResult<T>?)
abstract fun onFailer(result: HttpResult<T>?)
@SuppressLint("NewApi")
fun onRequestFailure(e: Throwable?) {
val result: HttpResult<T> = HttpResult()
result.code = -100
result.reason = e?.message
result.status = "failed"
onFailer(result)
}
@SuppressLint("NewApi")
fun onRequestSuccess(result: HttpResult<T>) {
onSuccess(result)
}
}
\ No newline at end of file
package com.yidian.common.http
import android.content.Context
interface IBaseView {
object LifeEvent {
const val CREATE = 0x01
const val START = 0x02
const val RESUME = 0x03
const val PAUSE = 0x04
const val STOP = 0x05
const val DESTROY = 0x06
}
/**
* 获取上下文对象
*
* @return
*/
val context: Context
/**
* 显示进度条
*
* @param message 要显示的信息
*/
fun showLoading(message: String?)
/**
* 显示进度条
*/
fun showLoading()
/**
* 隐藏进度条
*/
fun dismissLoading()
}
\ No newline at end of file
package com.yidian.common.http
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.ObservableTransformer
import io.reactivex.rxjava3.schedulers.Schedulers
class TransformUtil {
companion object{
fun <T> defaultSchedulers(): ObservableTransformer<T, T>? {
return ObservableTransformer { upstream: Observable<T> ->
upstream.observeOn(
AndroidSchedulers.mainThread()
).subscribeOn(Schedulers.io())
}
}
fun <T> allIo(): ObservableTransformer<T, T>? {
return ObservableTransformer { upstream: Observable<T> ->
upstream.observeOn(
Schedulers.io()
).subscribeOn(Schedulers.io())
}
}
}
}
\ No newline at end of file
package com.yidian.common.http
import com.yidian.common.BuildConfig
class URLs {
companion object{
val BASE_URL: String
private const val BASE_URL_DEBUG = "http://metro-test.go2yd.com"
private const val BASE_URL_PRO = "http://metro.go2yd.com"
init {
BASE_URL = if (BuildConfig.ENV_DEBUG){
BASE_URL_DEBUG
}else{
BASE_URL_PRO
}
}
const val guestLogin = "/login/login/guest"
const val sendSmsCode = "/login/login/send_sms_code"
const val mobileLogin = "/login/login/mobile_login"
const val videoCommentList = "/content/comment/list"
const val videoAddComment = "/content/comment/add"
const val addCollection = "/user/collect/add"
const val delCollection = "/user/collect/del"
const val logout = "/login/login/logout"
const val userInfo = "/user/user/info"
const val userInfoAll = "/user/user/info_all"
const val getExpression = "/content/comment/expression"
const val likeComment = "/content/comment/like"
const val contentDetail = "/content/content/get"
const val articleLike = "/content/thumbsup/thumbsup"
const val authorInfo = "/wemedia/profile/info"
const val authorFlow = "/wemedia/flow/homepage"
const val addSubscribe = "/user/subscribe/add"
const val deleteSubscribe = "/user/subscribe/delete"
const val subscribeFlow = "/flow/subscribe/wm_list"
const val recommendFlow = "/flow/recommend/list"
const val modifyNickname = "/user/user/modify_nickname"
const val uploadFile = "/user/user/modify_profile"
const val collectList = "/user/collect/list"
const val subscribeAuthorList = "/user/subscribe/list"
const val pushTokenAndroid = "/push/token/android"
}
}
\ No newline at end of file
package com.yidian.common.http.httpbean
import com.yidian.common.http.HttpResult
import com.yidian.common.http.IBaseView
interface IApiCallback: IBaseView {
fun loginCallBack(t: HttpResult<LoginBean.Response?>?)
}
\ No newline at end of file
package com.yidian.common.http.httpbean
class LoginBean (var request : Request,var response : Response){
data class Request(var mobileNo : String, var smsCode : String)
data class Response(var hasBindGatheringCard : String, var token : String)
}
package com.yidian.common.http.httpbean
/**
* FileName: WebResult
* Author: sym
* Date: 2021/3/5 2:26 PM
*/
class WebResult<T>(action: String, data: T) {
var action = action
var params: T? = data
}
\ No newline at end of file
package com.yidian.common.refresh
import android.content.Context
import android.graphics.drawable.AnimationDrawable
import android.util.AttributeSet
import android.view.View
import android.widget.FrameLayout
import android.widget.ImageView
import com.scwang.smart.refresh.layout.api.RefreshFooter
import com.scwang.smart.refresh.layout.api.RefreshHeader
import com.scwang.smart.refresh.layout.api.RefreshKernel
import com.scwang.smart.refresh.layout.api.RefreshLayout
import com.scwang.smart.refresh.layout.constant.RefreshState
import com.scwang.smart.refresh.layout.constant.SpinnerStyle
import com.yidian.common.R
class CustomFooter @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null,
defStyle: Int = 0
) : FrameLayout(context, attributeSet, defStyle) , RefreshFooter{
private var animDrawable: AnimationDrawable
init {
View.inflate(context, R.layout.layout_refresh_footer,this)
val imageView = findViewById<ImageView>(R.id.iv_loading)
animDrawable = imageView.drawable as AnimationDrawable
}
override fun getSpinnerStyle(): SpinnerStyle {
return SpinnerStyle.Translate
}
override fun onFinish(refreshLayout: RefreshLayout, success: Boolean): Int {
return 500
}
override fun onInitialized(kernel: RefreshKernel, height: Int, maxDragHeight: Int) {
}
override fun onHorizontalDrag(percentX: Float, offsetX: Int, offsetMax: Int) {
}
override fun setNoMoreData(noMoreData: Boolean): Boolean {
return noMoreData
}
override fun onReleased(refreshLayout: RefreshLayout, height: Int, maxDragHeight: Int) {
}
override fun getView(): View {
return this
}
override fun setPrimaryColors(vararg colors: Int) {
}
override fun onStartAnimator(refreshLayout: RefreshLayout, height: Int, maxDragHeight: Int) {
animDrawable.start()
}
override fun onStateChanged(
refreshLayout: RefreshLayout,
oldState: RefreshState,
newState: RefreshState
) {
if (oldState == RefreshState.LoadFinish&& newState == RefreshState.None){
animDrawable.stop()
animDrawable.selectDrawable(0)
}
}
override fun onMoving(
isDragging: Boolean,
percent: Float,
offset: Int,
height: Int,
maxDragHeight: Int
) {
}
override fun isSupportHorizontalDrag(): Boolean {
return false
}
}
\ No newline at end of file
package com.yidian.common.refresh
import android.content.Context
import android.graphics.drawable.AnimationDrawable
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.widget.FrameLayout
import android.widget.ImageView
import com.scwang.smart.refresh.layout.api.RefreshHeader
import com.scwang.smart.refresh.layout.api.RefreshKernel
import com.scwang.smart.refresh.layout.api.RefreshLayout
import com.scwang.smart.refresh.layout.constant.RefreshState
import com.scwang.smart.refresh.layout.constant.SpinnerStyle
import com.yidian.common.R
class CustomHeader @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null,
defStyle: Int = 0
) : FrameLayout(context, attributeSet, defStyle) ,RefreshHeader{
private val TAG = "CustomHeader"
private var animDrawable:AnimationDrawable
init {
View.inflate(context, R.layout.layout_refresh,this)
val imageView = findViewById<ImageView>(R.id.iv_loading)
animDrawable = imageView.drawable as AnimationDrawable
}
override fun getSpinnerStyle(): SpinnerStyle {
return SpinnerStyle.Translate
}
override fun onFinish(refreshLayout: RefreshLayout, success: Boolean): Int {
return 500
}
override fun onInitialized(kernel: RefreshKernel, height: Int, maxDragHeight: Int) {
}
override fun onHorizontalDrag(percentX: Float, offsetX: Int, offsetMax: Int) {
}
override fun onReleased(refreshLayout: RefreshLayout, height: Int, maxDragHeight: Int) {
}
override fun getView(): View {
return this
}
override fun setPrimaryColors(vararg colors: Int) {
}
override fun onStartAnimator(refreshLayout: RefreshLayout, height: Int, maxDragHeight: Int) {
animDrawable.start()
}
override fun onStateChanged(
refreshLayout: RefreshLayout,
oldState: RefreshState,
newState: RefreshState
) {
if(oldState==RefreshState.RefreshFinish && newState ==RefreshState.None){
animDrawable.stop()
animDrawable.selectDrawable(0)
}
}
override fun onMoving(
isDragging: Boolean,
percent: Float,
offset: Int,
height: Int,
maxDragHeight: Int
) {
}
override fun isSupportHorizontalDrag(): Boolean {
return false
}
}
\ No newline at end of file
package com.yidian.common.refresh
import android.animation.ValueAnimator
import android.content.Context
import android.util.AttributeSet
import android.util.Log
import com.scwang.smart.refresh.layout.SmartRefreshLayout
import com.scwang.smart.refresh.layout.api.RefreshComponent
import com.scwang.smart.refresh.layout.api.RefreshContent
import com.scwang.smart.refresh.layout.api.RefreshKernel
import com.scwang.smart.refresh.layout.api.RefreshLayout
import com.scwang.smart.refresh.layout.constant.RefreshState
class CustomSmartRefreshLayout @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null
) : SmartRefreshLayout(context, attributeSet) {
init {
mKernel = InnerImpl(RefreshKernelImpl())
}
private var onMoving: ((Int) -> Unit)? = null
fun setOnLoadMoreMovingListener(onMoving: (Int) -> Unit) {
this.onMoving = onMoving
}
inner class InnerImpl(private val realKernelImpl: RefreshKernel) : RefreshKernel {
override fun requestNeedTouchEventFor(
internal: RefreshComponent,
request: Boolean
): RefreshKernel {
realKernelImpl.requestNeedTouchEventFor(internal, request)
return this
}
override fun requestRemeasureHeightFor(internal: RefreshComponent): RefreshKernel {
realKernelImpl.requestRemeasureHeightFor(internal)
return this
}
override fun moveSpinner(spinner: Int, isDragging: Boolean): RefreshKernel {
onMoving?.invoke(spinner)
realKernelImpl.moveSpinner(spinner, isDragging)
return this
}
override fun getRefreshLayout(): RefreshLayout {
return refreshLayout
}
override fun setState(state: RefreshState): RefreshKernel {
realKernelImpl.setState(state)
return this
}
override fun requestFloorBottomPullUpToCloseRate(rate: Float): RefreshKernel {
realKernelImpl.requestFloorBottomPullUpToCloseRate(rate)
return this
}
override fun requestDefaultTranslationContentFor(
internal: RefreshComponent,
translation: Boolean
): RefreshKernel {
realKernelImpl.requestDefaultTranslationContentFor(internal, translation)
return this
}
override fun requestFloorDuration(duration: Int): RefreshKernel {
realKernelImpl.requestFloorDuration(duration)
return this
}
override fun animSpinner(endSpinner: Int): ValueAnimator {
return realKernelImpl.animSpinner(endSpinner)
}
override fun requestDrawBackgroundFor(
internal: RefreshComponent,
backgroundColor: Int
): RefreshKernel {
realKernelImpl.requestDrawBackgroundFor(internal, backgroundColor)
return this
}
override fun getRefreshContent(): RefreshContent {
return refreshContent
}
override fun startTwoLevel(open: Boolean): RefreshKernel {
realKernelImpl.startTwoLevel(open)
return this
}
override fun finishTwoLevel(): RefreshKernel {
realKernelImpl.finishTwoLevel()
return this
}
}
}
\ No newline at end of file
package com.yidian.common.services.BsNewsContentTest
import com.yidian.common.base.BaseFragment
import com.yidian.yac.core.core.YacRouteNode
import com.yidian.yac.core.zap.ZapService
abstract class NewsTest: ZapService() {
abstract fun log()
}
\ No newline at end of file
package com.yidian.common.services
import com.yidian.common.base.BaseFragment
abstract class FragmentFactory :ZapServiceAdapter(){
abstract fun getFragment(path:String):BaseFragment<*>?
}
\ No newline at end of file
### 所有公共服务接口放在该目录下
\ No newline at end of file
package com.yidian.common.services
import android.util.Log
import com.yidian.xarc.xbrid.XBridManager
import com.yidian.xarc.xevent.XBaseEvent
import com.yidian.xarc.xevent.XEventManager
import com.yidian.xarc.xrouter.ResultResolver
import com.yidian.yac.core.zap.ZapService
import com.yidian.yac.core.zap.ZapTicket
import org.json.JSONObject
/**
* @description: xevent支持类
* @author: huyajun
* @date: 2020/9/27
**/
class XEventService : ZapService() {
override fun onAction(
path: String,
action: String,
params: Any,
options: Any,
resolver: ResultResolver
) {
when (action) {
"postEvent" -> {
params as JSONObject
val name: String = params["name"] as String
val body = params["body"]
XEventManager.post(XBaseEvent(name, body))
//向flutter发送Event事件
ZapTicket("flutter-event")
.withAction("handleEvent")
.withServiceParams(params)
.onLost { result ->
Log.d(TAG, "onLost: $result")
}
.onResult { result ->
Log.d(TAG, "flutter-event+onResult: $result")
}.ship()
XBridManager.postEvent(name, body, null)
resolver.success("事件已发送")
}
}
}
override fun onInit() {
}
override fun onExit() {
}
companion object {
const val name: String = "xevent"
private val TAG = "XEventService"
fun postEvent(xbaseEvent: XBaseEvent) {
val jsonObject = JSONObject()
jsonObject.put("name", xbaseEvent.name)
jsonObject.put("body", xbaseEvent.body)
ZapTicket(name)
.withAction("postEvent")
.withServiceParams(jsonObject)
.onLost { result ->
Log.d(TAG, "onLost: $result")
}
.onResult { result ->
Log.d(TAG, "onResult: $result")
}.ship()
}
}
}
\ No newline at end of file
package com.yidian.common.services
import com.yidian.xarc.xrouter.ResultResolver
import com.yidian.xpage.XPageManager
import com.yidian.yac.core.zap.ZapService
/**
* @description: xpage服务类
* @author: huyajun
* @date: 2020/9/27
**/
class XPageService : ZapService() {
companion object {
const val name: String = "xpage"
}
override fun onAction(
path: String,
action: String,
params: Any,
options: Any,
resolver: ResultResolver
) {
params as Map<String, Any>
val name = params["pageName"] as String
val pageParams = params["pageParams"] as Map<String, Any>
when (action) {
"push" -> {
XPageManager.push(name, pageParams)
}
"pop" -> {
XPageManager.pop(pageParams)
}
"popTo" -> {
XPageManager.popTo(name, pageParams)
}
"popToRoot" -> {
XPageManager.popToRoot(pageParams)
}
}
}
override fun onInit() {
}
override fun onExit() {
}
}
\ No newline at end of file
package com.yidian.common.services
import com.yidian.xarc.xrouter.ResultResolver
import com.yidian.yac.core.zap.ZapService
abstract class ZapServiceAdapter :ZapService (){
override fun onAction(
path: String,
action: String,
params: Any,
options: Any,
resolver: ResultResolver
) {}
override fun onExit() {}
override fun onInit() {}
}
\ No newline at end of file
package com.yidian.common.utils
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.util.Log
class CheckApkExistUtil {
companion object{
const val weChatPkgName = "com.tencent.mm"
const val mobileQQPkgName = "com.tencent.mobileqq"
const val sinaBlogPkgName = "com.sina.weibo"
fun checkApkExist(context: Context, packageName: String): Boolean{
if(packageName.isEmpty()) return false
var packageInfo: ApplicationInfo?
try {
packageInfo = context.packageManager.getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES)
}catch (e: PackageManager.NameNotFoundException){
packageInfo = null
}
return packageInfo != null
}
}
}
\ No newline at end of file
package com.yidian.common.utils
import okhttp3.internal.and
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
class EncryptUtil {
companion object{
fun getMD5(info: String): String{
val md5: MessageDigest = MessageDigest.getInstance("MD5")
md5.update(info.toByteArray())
val m = md5.digest()
return byte2hex(m)
}
fun encryptToSHA(info: String): String{
val digesta: ByteArray
var rs = ""
try {
val alga: MessageDigest = MessageDigest.getInstance("SHA-1")
alga.update(info.toByteArray())
digesta = alga.digest()
rs = byte2hex(digesta)
} catch (e: NoSuchAlgorithmException) {
e.printStackTrace()
}
return rs
}
private fun byte2hex(b: ByteArray): String{
var hs = ""
var stmp: String
repeat(b.size){
stmp = Integer.toHexString(b[it] and 0XFF)
hs = if(stmp.length == 1){
hs + "0" + stmp
}else{
hs + stmp
}
}
return hs
}
}
}
\ No newline at end of file
package com.yidian.common.utils
class ImageConstants {
companion object{
const val IMAGE_SERVER_NEW = "http://i3.go2yd.com/image/"
const val IMAGE_SERVER_SHORT_I3 = "i3.go2yd.com"
const val IMAGE_SERVER_SHORT_I1 = "i1.go2yd.com"
}
}
\ No newline at end of file
package com.yidian.common.utils
import android.content.Context
import cn.jiguang.verifysdk.api.JVerificationInterface
import com.yidian.common.BuildConfig
class JVerificationUtils {
companion object {
fun init(context: Context) {
JVerificationInterface.setDebugMode(BuildConfig.DEBUG)
JVerificationInterface.init(context)
}
}
}
package com.yidian.common.utils
import android.content.Context
import android.net.ConnectivityManager
import android.telephony.TelephonyManager
class NetWorkUtils {
companion object{
const val NET_TYPE_WIFI = "wifi"
const val NET_TYPE_4G = "4g"
const val NET_TYPE_5G = "5g"
const val NET_TYPE_3G = "3g"
const val NET_TYPE_2G = "2g"
fun getNetWorkType(context: Context): String{
var netType = "unknown"
val manager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val networkInfo = manager.activeNetworkInfo ?: return netType
val nType = networkInfo.type
if (nType == ConnectivityManager.TYPE_WIFI) {
netType = "wifi"
} else if (nType == ConnectivityManager.TYPE_MOBILE) {
val nSubType = networkInfo.subtype
val telephonyManager: TelephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
netType = if(nSubType ==TelephonyManager.NETWORK_TYPE_NR){
"5g"
} else if (nSubType == TelephonyManager.NETWORK_TYPE_LTE && !telephonyManager.isNetworkRoaming) {
"4g"
} else if (nSubType == TelephonyManager.NETWORK_TYPE_UMTS || nSubType == TelephonyManager.NETWORK_TYPE_HSDPA || (nSubType == TelephonyManager.NETWORK_TYPE_EVDO_0
&& !telephonyManager.isNetworkRoaming)) {
"3g"
} else if (nSubType == TelephonyManager.NETWORK_TYPE_GPRS || nSubType == TelephonyManager.NETWORK_TYPE_EDGE || (nSubType == TelephonyManager.NETWORK_TYPE_CDMA
&& !telephonyManager.isNetworkRoaming)) {
"2g"
} else {
"unknown"
}
}
return netType
}
fun isWifiConnected(context: Context):Boolean{
return NET_TYPE_WIFI == getNetWorkType(context)
}
}
}
\ No newline at end of file
package com.yidian.common.utils
import android.content.Context
import android.os.Build
import android.util.Log
import android.util.TypedValue
import com.google.gson.Gson
import com.google.gson.JsonObject
import com.orhanobut.hawk.Hawk
import com.yidian.common.AppConfig
import com.yidian.common.HawkConfig
import com.yidian.common.XRouterPathConstants
import com.yidian.common.http.httpbean.WebResult
import com.yidian.common.services.XEventService
import com.yidian.utils.MD5Util
import com.yidian.xarc.xbrid.XBridManager
import com.yidian.xarc.xbrid.XWebView
import com.yidian.xarc.xevent.XBaseEvent
import com.yidian.xpage.XPageManager
import com.yidian.yac.ftdevicefinger.core.FtDeviceFingerManager
import org.json.JSONObject
import java.util.*
object ToolsUtil {
//防止连续点击
private var lastClickTime: Long = 0
//自定义快速点击时间
private var currentLastClickTime: Long = 0
//备用自定义快速点击时间
private var tempLastClickTime: Long = 0
//快速点击检测
val isFastClick: Boolean
get() {
val time = System.currentTimeMillis()
val timeD = time - lastClickTime
if (timeD < 500) {
return false
}
lastClickTime = time
return true
}
//单位转换
fun dp2px(context: Context, dpVal: Float): Int {
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dpVal,
context.resources.displayMetrics
).toInt()
}
//格式化展示
fun formatShowNum(count: Int): String{
var showCount = count.toString()
when{
count in 1000..9999 -> {
val floutCount = count / 1000
showCount = floutCount.toString().format("%.1f") + "K"
}
count in 10000..99999999 -> {
val floutCount = count / 10000
showCount = floutCount.toString().format("%.1f") + "W"
}
count >= 100000000 -> {
val floutCount = count / 100000000
showCount = floutCount.toString().format("%.1f") + "亿"
}
}
return showCount
}
//event事件
fun doAction(name: String, params: Any) {
Log.d("song_test", "event_bus.name = $name")
val xBaseEvent = XBaseEvent(name, params)
XEventService.postEvent(xBaseEvent)
}
//自定义时间检测
fun isCustomFastClick(timeNum: Long): Boolean {
val time = System.currentTimeMillis()
val timeD = time - currentLastClickTime
if (timeD < timeNum) {
return false
}
currentLastClickTime = time
return true
}
//备用自定义时间检测
fun isCustomFastStatus(timeNum: Long): Boolean {
val time = System.currentTimeMillis()
val timeD = time - tempLastClickTime
if (timeD < timeNum) {
return false
}
tempLastClickTime = time
return true
}
//机型判断
fun judgePhone(): Boolean {
val manufacturer: String = Build.MANUFACTURER
return if (manufacturer.isNotEmpty()) {
when (manufacturer.toLowerCase(Locale.ROOT)) {
"oppo" -> true
"xiaomi" -> true
else -> false
}
} else false
}
//web交互
fun directSend(str: String, content: String, webView: XWebView) {
val tempData = Gson().fromJson(content, JsonObject::class.java)
val webResult = WebResult(str, tempData)
val temp = JSONObject(Gson().toJson(webResult))
XBridManager.postEvent("CommentService", temp, webView)
}
fun isLogin(): Boolean {
return if (Hawk.get(HawkConfig.LoginStatus, false)) {
true
} else {
val paramsMap = HashMap<String, String>()
paramsMap["popName"] = XRouterPathConstants.NEWS_CONTENT
XPageManager.push(XRouterPathConstants.LOGIN, paramsMap)
false
}
}
fun getYDEncryptionToken(): String {
val temp = StringBuilder()
//架构组提供的设备指纹
temp.append(AppConfig.appid)
Log.d("song_test","appid = " + AppConfig.appid)
temp.append(FtDeviceFingerManager.getDeviceFinger())
Log.d("song_test","getDeviceFinger = "+FtDeviceFingerManager.getDeviceFinger())
return "UMPPTYKO" + MD5Util.md5Encrypt32Upper(temp.toString())
}
fun getDeviceBrandMask(): Int {
val brand = Build.BRAND
var mask = 64 //0100 0000
if ("huawei".equals(brand, ignoreCase = true) || "honor".equals(brand, ignoreCase = true)) {
mask = 32 //0010 0000
} else if ("meizu".equals(brand, ignoreCase = true)) {
mask = 48 //0011 0000
} else if ("xiaomi".equals(brand, ignoreCase = true)) {
mask = 16 //0001 0000
} else if ("nubia".equals(brand, ignoreCase = true)) {
mask = 80 //0101 0000
} else if ("ZTE".equals(brand, ignoreCase = true)) {
mask = 96 //0110 0000
} else if ("oppo".equals(brand, ignoreCase = true)) {
mask = 112 //0111 0000
} else if ("vivo".equals(brand, ignoreCase = true)) {
mask = 128 //0001 0000 0000
} else if ("samsung".equals(brand, ignoreCase = true)) {
mask = 144 //0001 0001 0000
}
return mask
}
}
\ No newline at end of file
package com.yidian.common.utils
import android.content.Context
import android.graphics.Typeface
import com.yidian.common.YdBaseApplication
import kotlin.concurrent.thread
class TypefaceUtil {
companion object{
val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED){
TypefaceUtil()
}
}
var typeface:Typeface? = null
fun initTypeface(context: Context) {
typeface= Typeface.createFromAsset(context.assets,"font/SourceHanSerifCN-Bold-2.otf")
// typeface= Typeface.createFromAsset(context.assets,"font/DIN Alternate Bold.ttf")
}
}
\ No newline at end of file
package com.yidian.common.utils
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import com.orhanobut.hawk.Hawk
import com.umeng.commonsdk.UMConfigure
import com.umeng.message.IUmengRegisterCallback
import com.umeng.message.PushAgent
import com.umeng.message.UmengMessageHandler
import com.umeng.message.UmengNotificationClickHandler
import com.umeng.message.entity.UMessage
import com.umeng.socialize.PlatformConfig
import com.yidian.common.AppConfig
import com.yidian.common.HawkConfig
import com.yidian.common.XRouterPathConstants
import com.yidian.xpage.XPageManager
/**
* 友盟错误统计、push辅助类
* */
class UMConfigUtils {
companion object {
fun init(context: Context) {
// when (BuildConfig.DEBUG) {
// false -> {
//release环境上报错误信息,参数有:上下文、APPkey、渠道号、设备类型、推送密钥
UMConfigure.init(context, AppConfig.UMAppKey, AppConfig.UMChannel, UMConfigure.DEVICE_TYPE_PHONE, AppConfig.UMSecret)
PlatformConfig.setWeixin(AppConfig.WeChatAppKey, AppConfig.WeChatAppSecret)
PlatformConfig.setWXFileProvider(AppConfig.FileProvider)
PlatformConfig.setQQZone(AppConfig.QQAppKey, AppConfig.QQAppSecret)
PlatformConfig.setQQFileProvider(AppConfig.FileProvider)
PlatformConfig.setSinaWeibo(AppConfig.SinaAppKey, AppConfig.SinaAppSecret, AppConfig.SinaCallBackUrl)
val mPushAgent = PushAgent.getInstance(context)
mPushAgent.register(object : IUmengRegisterCallback {
override fun onSuccess(deviceToken: String) {
//注册成功会返回deviceToken deviceToken是推送消息的唯一标志
Log.i("umpush", "注册成功:deviceToken:--------> $deviceToken")
Hawk.put(HawkConfig.UmToken, deviceToken)
addAlias()
}
private fun addAlias() {
val token = ToolsUtil.getYDEncryptionToken()
mPushAgent.addAlias(token, AppConfig.UMType) { isSuccess, message ->
Log.d("song_test", "addAlias 绑定成功与否 = $isSuccess message = $message")
}
}
override fun onFailure(s: String, s1: String) {
Log.e("umpush", "注册失败:--------> s:$s,s1:$s1")
}
})
val messageHandler = object : UmengMessageHandler() {
override fun dealWithCustomMessage(p0: Context?, p1: UMessage?) {
super.dealWithCustomMessage(p0, p1)
Log.e("umpush", "dealWithCustomMessage接收自定义消息:--------> ${p1!!.custom}")
}
}
val notificationClickHandler: UmengNotificationClickHandler = object : UmengNotificationClickHandler() {
override fun dealWithCustomAction(context: Context, msg: UMessage) {
super.dealWithCustomAction(context, msg)
Toast.makeText(context, msg.custom, Toast.LENGTH_LONG).show()
Log.e("umpush", "dealWithCustomAction接收消息:--------> ${msg.custom}")
}
override fun launchApp(p0: Context?, p1: UMessage?) {
super.launchApp(p0, p1)
goToJump(p1)
}
override fun openUrl(p0: Context?, p1: UMessage?) {
super.openUrl(p0, p1)
Log.e("umpush", "openUrl接收自定义消息:--------> ${p1!!.custom}")
}
override fun openActivity(p0: Context?, p1: UMessage?) {
super.openActivity(p0, p1)
Log.e("umpush", "openActivity接收自定义消息:--------> ${p1!!.custom}")
}
}
mPushAgent.notificationClickHandler = notificationClickHandler
mPushAgent.messageHandler = messageHandler
}
private fun goToJump(p1: UMessage?) {
//点击跳转参数
val paramsMap = HashMap<String, Any?>()
//接收到的参数
val extras: Map<String, String>? = p1?.extra
val b = Bundle()
if (extras != null) {
for (key in extras.keys) {
b.putString(key, extras[key])
}
}
//配置数据
if (b.get("rstype") != null && b.get("docid") != null) {
paramsMap["jumpFrom"] = "PushJump"
paramsMap["doc_id"] = b.get("docid")
when (b.get("rstype")) {
"normal" -> paramsMap["content_type"] = "text_detail"
"video" -> paramsMap["content_type"] = "video_detail"
}
XPageManager.push(XRouterPathConstants.NEWS_MAIN, paramsMap)
}
}
// true -> {
// //debug环境打开日志输出,默认关闭
// UMConfigure.setLogEnabled(true)
// }
// }
// }
}
}
package com.yidian.common.utils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.LayoutRes
import androidx.recyclerview.widget.RecyclerView
class ViewHolderUtil {
companion object{
fun RecyclerView.Adapter<out RecyclerView.ViewHolder>.createItemView(parent:ViewGroup,@LayoutRes layoutId:Int):View{
return LayoutInflater.from(parent.context).inflate(layoutId,parent,false)
}
}
}
\ No newline at end of file
package com.yidian.common.utils;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.view.View;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import java.io.File;
import java.io.OutputStream;
import java.util.Hashtable;
public class YdFileUtils {
public static Bitmap createBitmap(View view){
if (view == null) return null;
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null) {
bgDrawable.draw(canvas);
} else {
canvas.drawColor(Color.WHITE);
}
view.draw(canvas);
return bitmap;
}
public static boolean deleteFile(String delFile) {
File file = new File(delFile);
if(file.exists() && file.isFile()){
return file.delete();
}
return false;
}
public static String saveImageFromView(Context context, Bitmap bitmap){
String fileName = "YdSubway_" + System.currentTimeMillis() + ".png";
try {
ContentValues contentValues = new ContentValues();
//设置文件名
contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, fileName);
//兼容Android Q和以下版本
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, "DCIM/");
} else {
contentValues.put(MediaStore.Images.Media.DATA, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath());
}
contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/PNG");
Uri uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
if (uri != null) {
OutputStream outputStream = context.getContentResolver().openOutputStream(uri);
if (outputStream != null) {
bitmap.compress(Bitmap.CompressFormat.PNG, 90, outputStream);
outputStream.flush();
outputStream.close();
}
}
return getImageAbsolutePath(context, uri);
} catch (Exception e) {
}
return "";
}
public static String getImageAbsolutePath (Context context, Uri imageUri) {
if (context == null || imageUri == null)
return null;
if (DocumentsContract.isDocumentUri(context, imageUri)) {
if (isExternalStorageDocument(imageUri)) {
String docId = DocumentsContract.getDocumentId(imageUri);
String[] split = docId.split(":");
String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
} else if (isDownloadsDocument(imageUri)) {
String id = DocumentsContract.getDocumentId(imageUri);
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
} else if (isMediaDocument(imageUri)) {
String docId = DocumentsContract.getDocumentId(imageUri);
String[] split = docId.split(":");
String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
String selection = MediaStore.Images.Media._ID + "=?";
String[] selectionArgs = new String[]{split[1]};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}else if ("content".equalsIgnoreCase(imageUri.getScheme())) {
if (isGooglePhotosUri(imageUri))
return imageUri.getLastPathSegment();
return getDataColumn(context, imageUri, null, null);
}else if ("file".equalsIgnoreCase(imageUri.getScheme())) {
return imageUri.getPath();
}
return null;
}
private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {column};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
private static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
private static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
private static boolean isDownloadsDocument (Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
private static boolean isMediaDocument (Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
public static Bitmap createQRCodeBitmap(String content, int width,int height){
return createQRCodeBitmap(content, width, height, "UTF-8", "H", "0", Color.BLACK, Color.WHITE);
}
/**
* 生成简单二维码
*
* @param content 字符串内容
* @param width 二维码宽度
* @param height 二维码高度
* @param character_set 编码方式(一般使用UTF-8)
* @param error_correction_level 容错率 L:7% M:15% Q:25% H:35%
* @param margin 空白边距(二维码与边框的空白区域)
* @param color_black 黑色色块
* @param color_white 白色色块
* @return BitMap
*/
public static Bitmap createQRCodeBitmap(String content, int width,int height,
String character_set,String error_correction_level,
String margin,int color_black, int color_white) {
// 字符串内容判空
if (TextUtils.isEmpty(content)) {
return null;
}
// 宽和高>=0
if (width < 0 || height < 0) {
return null;
}
try {
/** 1.设置二维码相关配置 */
Hashtable<EncodeHintType, String> hints = new Hashtable<>();
// 字符转码格式设置
if (!TextUtils.isEmpty(character_set)) {
hints.put(EncodeHintType.CHARACTER_SET, character_set);
}
// 容错率设置
if (!TextUtils.isEmpty(error_correction_level)) {
hints.put(EncodeHintType.ERROR_CORRECTION, error_correction_level);
}
// 空白边距设置
if (!TextUtils.isEmpty(margin)) {
hints.put(EncodeHintType.MARGIN, margin);
}
/** 2.将配置参数传入到QRCodeWriter的encode方法生成BitMatrix(位矩阵)对象 */
BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
/** 3.创建像素数组,并根据BitMatrix(位矩阵)对象为数组元素赋颜色值 */
int[] pixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
//bitMatrix.get(x,y)方法返回true是黑色色块,false是白色色块
if (bitMatrix.get(x, y)) {
pixels[y * width + x] = color_black;//黑色色块像素设置
} else {
pixels[y * width + x] = color_white;// 白色色块像素设置
}
}
}
/** 4.创建Bitmap对象,根据像素数组设置Bitmap每个像素点的颜色值,并返回Bitmap对象 */
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
} catch (WriterException e) {
e.printStackTrace();
return null;
}
}
}
package com.yidian.common.utils
import android.content.Context
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.Toast
import com.bumptech.glide.Glide
import com.yidian.common.R
import com.yidian.nightmode.widget.YdImageView
import com.yidian.nightmode.widget.YdTextView
class YdToastUtil {
companion object{
fun showToast(context: Context, message: String){
val toastView = LayoutInflater.from(context).inflate(R.layout.toast_layout, null)
val tvContent = toastView.findViewById<YdTextView>(R.id.tv_content)
tvContent.text = message
val toast = Toast(context)
toast.duration = Toast.LENGTH_SHORT
toast.view = toastView
toast.show()
}
fun showToast(context: Context, message: String, imageUrl: String){
val toastView = LayoutInflater.from(context).inflate(R.layout.toast_layout, null)
val ivIcon = toastView.findViewById<ImageView>(R.id.iv_icon)
Glide.with(context).load(imageUrl).into(ivIcon)
ivIcon.visibility = View.VISIBLE
val tvContent = toastView.findViewById<YdTextView>(R.id.tv_content)
tvContent.text = message
val toast = Toast(context)
toast.duration = Toast.LENGTH_SHORT
toast.view = toastView
toast.show()
}
fun refreshToast(context: Context, message: String){
val toastView = LayoutInflater.from(context).inflate(R.layout.refresh_toast_layout, null)
val tvContent = toastView.findViewById<YdTextView>(R.id.tv_content)
tvContent.text = message
val toast = Toast(context)
toast.duration = Toast.LENGTH_SHORT
toast.view = toastView
toast.setGravity(Gravity.CENTER_HORIZONTAL or Gravity.TOP,0,350)
toast.show()
}
}
}
\ No newline at end of file
package com.yidian.common.utils
import android.content.Context
class YdUiUtils {
companion object{
fun dip2px(dip: Int, context: Context): Int{
val scale = context.resources.displayMetrics.density
return (dip * scale + 0.5F).toInt()
}
}
}
\ No newline at end of file
package com.yidian.common.widget
import android.app.Activity
import android.app.Dialog
import android.os.Bundle
import android.view.Gravity
import android.view.WindowManager
import com.yidian.common.R
import com.yidian.nightmode.widget.YdTextView
class NormalHintDialog(private val activity: Activity, themeResId: Int): Dialog(activity, themeResId) {
companion object{
const val DELETE = "delete"
const val CLEAR = "clear"
}
lateinit var tvContent: YdTextView
lateinit var tvDelete: YdTextView
private lateinit var tvCancel: YdTextView
init {
setDialog()
}
private fun setDialog(){
this.setCanceledOnTouchOutside(false)
this.setContentView(R.layout.dialog_normal)
this.setOwnerActivity(activity)
tvContent = findViewById(R.id.tv_content)
tvDelete = findViewById(R.id.tv_delete)
tvCancel = findViewById(R.id.tv_cancel)
setClickListener()
}
private fun setClickListener(){
tvCancel.setOnClickListener {
dismiss()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val params: WindowManager.LayoutParams? = window?.attributes
params?.width = WindowManager.LayoutParams.MATCH_PARENT
params?.height = WindowManager.LayoutParams.WRAP_CONTENT
window?.attributes = params
window?.attributes?.gravity = Gravity.CENTER
}
}
\ No newline at end of file
package com.yidian.common.widget
import android.content.Context
import android.content.res.AssetManager
import android.graphics.Typeface
import android.util.AttributeSet
import com.yidian.nightmode.widget.YdTextView
class NumberFontTextView @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null,
defStyle: Int = 0
) : YdTextView(context, attributeSet, defStyle) {
init {
val typeface= Typeface.createFromAsset(context.assets,"font/DINPro-Bold.ttf")
setTypeface(typeface)
}
}
\ No newline at end of file
package com.yidian.common.widget
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Rect
import android.util.AttributeSet
import com.yidian.common.R
import com.yidian.common.utils.TypefaceUtil
import com.yidian.common.utils.YdUiUtils
import com.yidian.nightmode.widget.YdTextView
class TextFontTextView @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null,
defStyle: Int = 0
) : YdTextView(context, attributeSet, defStyle) {
private val TAG = "TextFontTextView"
private val rect by lazy { Rect() }
private var showUnderLine = false
var underLineHeight = YdUiUtils.dip2px(9,context)
set(value) {
field = YdUiUtils.dip2px(value,context)
}
private val underRect:Rect by lazy { Rect() }
private val underPaint:Paint by lazy { Paint() }
init {
typeface = TypefaceUtil.instance.typeface
}
fun showUnderLine(){
showUnderLine = true
invalidate()
}
fun hideUnderLine(){
showUnderLine = false
invalidate()
}
override fun onDraw(canvas: Canvas?) {
if (showUnderLine) {
paint.getTextBounds(text.toString(),0,text.length,rect)
underPaint.color = context.resources.getColor(R.color.mainYellowColor)
underPaint.style = Paint.Style.FILL
underRect.bottom = baseline+paint.fontMetrics.descent.toInt()
underRect.left = 0
underRect.top = baseline+paint.fontMetrics.descent.toInt()-underLineHeight
underRect.right = rect.right
canvas?.drawRect(underRect,underPaint)
}
super.onDraw(canvas)
}
}
\ No newline at end of file
package com.yidian.common.widget
import android.content.Context
import android.util.AttributeSet
import com.yidian.nightmode.widget.YdRecyclerView
class YdMaxRecyclerView @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null,
defStyle: Int = 0
): YdRecyclerView(context, attributeSet, defStyle) {
override fun onMeasure(widthSpec: Int, heightSpec: Int) {
val expandSpec = MeasureSpec.makeMeasureSpec(Int.MAX_VALUE shr 2, MeasureSpec.AT_MOST)
super.onMeasure(widthSpec, expandSpec)
}
}
\ No newline at end of file
package com.yidian.common.widget.chameleon;
import android.content.Context;
import com.yidian.chameleon.annotation.BindingData;
import com.yidian.chameleon.annotation.SetAttribute;
import com.yidian.chameleon.annotation.ViewParserFactory;
import com.yidian.chameleon.value.base.BooleanValueParser;
import com.yidian.chameleon.value.base.IntegerValueParser;
import com.yidian.chameleon.value.common.CommonColorValueParser;
import com.yidian.chameleon.value.common.CommonTextViewStringValueParser;
import com.yidian.nightmode_basic_widget.helper.NMTextColorResHelper;
import com.yidian.nightmode_basic_widget.parser.NMBaseViewParser;
@ViewParserFactory(viewName = "SubwayRichLabel", category = "YDSubway")
public class SubwayRichParser extends NMBaseViewParser<SubwayRichTextViewGroup> {
@BindingData
public void bindData(SubwayRichTextViewGroup view, String value, CommonTextViewStringValueParser valueParser) {
if (valueParser.canAppliedTo(value)) {
view.setValue(valueParser.apply(value));
}
}
@SetAttribute("clickable")
public void setClickable(SubwayRichTextViewGroup view, String value, BooleanValueParser valueParser) {
if (valueParser.canAppliedTo(value)) {
view.setViewClickable(valueParser.apply(value));
}
}
@SetAttribute("textColor")
public void setTextColor(SubwayRichTextViewGroup view, String value, CommonColorValueParser valueParser) {
if (valueParser.canAppliedTo(value)) {
if (valueParser.canAppliedTo(value)) {
view.setViewTextColor(valueParser.apply(value));
((NMTextColorResHelper.IResSetter) view).setTextColorResValue(value);
}
}
}
@SetAttribute("textSize")
public void setTextSize(SubwayRichTextViewGroup view, String value, IntegerValueParser valueParser) {
if (valueParser.canAppliedTo(value)) {
view.setViewTextSize(valueParser.apply(value));
}
}
@SetAttribute("fontStyle")
public void setFontStyle(SubwayRichTextViewGroup view, String value, CommonTextViewStringValueParser valueParser) {
if (valueParser.canAppliedTo(value)) {
view.setViewFontStyle(valueParser.apply(value));
}
}
@SetAttribute("cornerText")
public void setCornerText(SubwayRichTextViewGroup view, String value, CommonTextViewStringValueParser valueParser) {
if (valueParser.canAppliedTo(value)) {
view.setViewCornerText(valueParser.apply(value));
}
}
@SetAttribute("cornerTextColor")
public void setCornerTextColor(SubwayRichTextViewGroup view, String value, CommonColorValueParser valueParser) {
if (valueParser.canAppliedTo(value)) {
view.setViewCornerTextColor(valueParser.apply(value));
}
}
@SetAttribute("cornerTextSize")
public void setCornerTextSize(SubwayRichTextViewGroup view, String value, IntegerValueParser valueParser) {
if (valueParser.canAppliedTo(value)) {
view.setViewCornerTextSize(valueParser.apply(value));
}
}
@SetAttribute("maxLines")
public void setMaxLines(SubwayRichTextViewGroup view, String value, IntegerValueParser valueParser) {
if (valueParser.canAppliedTo(value)) {
view.setMaxLines(valueParser.apply(value));
}
}
@SetAttribute("showCornerAlways")
public void setShowCornerAlways(SubwayRichTextViewGroup view, String value, BooleanValueParser valueParser) {
if (valueParser.canAppliedTo(value)) {
view.setShowCornerAlways(valueParser.apply(value));
}
}
@Override
public SubwayRichTextViewGroup createView(Context context) {
return new SubwayRichTextViewGroup(context);
}
}
package com.yidian.common.widget.chameleon;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.Layout;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.ClickableSpan;
import android.text.style.TextAppearanceSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.yidian.nightmode.widget.YdTextView;
import static android.util.TypedValue.COMPLEX_UNIT_SP;
public class SubwayRichTextView extends YdTextView {
private static final String TAG = "SubwayRichTextView";
private String SUFFIX = "详情";
private SpannableString suffix;
private String resultMsg;
private boolean isClickable;
private int textColor = Color.parseColor("#191f2c");//tally_title_text
private int cornerTextColor = Color.parseColor("#657BA9");
private int textSize = getContentTextSize(), suffixTextSize = getSuffixTextSize(), maxLines = Integer.MAX_VALUE;
private Paint paint;
private boolean cornerAlwaysShow;
private String originalData;
public String getResultMsg() {
return resultMsg;
}
public void setSuffix(SpannableString suffix) {
this.suffix = suffix;
}
public SubwayRichTextView(Context context) {
this(context, null);
}
public SubwayRichTextView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public SubwayRichTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.setLineSpacing(0, 1.2f);
}
@Override
public void setText(CharSequence text, BufferType type) {
setEllipsize(TextUtils.TruncateAt.END);
super.setText(text, type);
}
@Override
protected void onDraw(Canvas canvas) {
CharSequence charSequence = getText();
Layout layout = getLayout();
if (layout == null) {
resultMsg = charSequence.toString().substring(7);
super.onDraw(canvas);
return;
}
if (TextUtils.isEmpty(suffix) || !isClickable){
//没有添加过后缀直接不处理按原始数据绘制
resultMsg = charSequence.toString();
super.onDraw(canvas);
return;
}
int textLines = layout.getLineCount();
//getEllipsisCount 获取省略的字符数,0表示没和省略
if (textLines < maxLines || layout.getEllipsisCount(textLines - 1) == 0) {
if (cornerAlwaysShow){
//如果是需要一直显示suffix则不处理按原数据绘制
resultMsg = charSequence.toString();
super.onDraw(canvas);
return;
}
if (TextUtils.isEmpty(originalData)){
resultMsg = charSequence.toString();
super.onDraw(canvas);
return;
}
drawTextWithoutSuffix(canvas);
return;
}
if (textLines == maxLines && layout.getEllipsisCount(textLines-1)==0){
if (cornerAlwaysShow){
//如果是需要一直显示suffix则不处理按原数据绘制
resultMsg = charSequence.toString();
super.onDraw(canvas);
return;
}
if (TextUtils.isEmpty(originalData)){
resultMsg = charSequence.toString();
super.onDraw(canvas);
return;
}
drawTextWithoutSuffix(canvas);
return;
}
// 获取最后一行的文字
int lastLineStart = layout.getLineStart(textLines - 1);
CharSequence textInLastLine = charSequence.subSequence(lastLineStart,
lastLineStart + layout.getEllipsisStart(textLines - 1));
Paint paint = layout.getPaint();
paint.setTextSize(textSize); // 如果字体更改大小后,修改textpaint的文字大小,measureText 才是正确的值
SpannableStringBuilder textInlastLineSuffix = addSuffix(textInLastLine);
float wLastLineEllipsis = paint.measureText(textInlastLineSuffix.toString());
int deleteLength = 0;
while (wLastLineEllipsis > layout.getEllipsizedWidth()) {
deleteLength = deleteLength + 2 + suffix.length();
if (textInLastLine.length() - deleteLength < 0) {
break;
}
textInLastLine = textInLastLine.subSequence(0, textInLastLine.length() - deleteLength);
textInlastLineSuffix = addSuffix(textInLastLine);
wLastLineEllipsis = paint.measureText(textInlastLineSuffix.toString());
}
@SuppressLint("DrawAllocation") SpannableStringBuilder result = new SpannableStringBuilder(charSequence.subSequence(0, lastLineStart + layout.getEllipsisStart(textLines - 1) - deleteLength));
resultMsg = result.toString();
result.append(addSuffix(""));
TextPaint tp = getPaint();
tp.setColor(getCurrentTextColor()); // 此处需要重新赋值,由于日夜间模式的色值最终是在super.onDraw 中设置给paint,此处没有调用super,因此手动设置色值。
@SuppressLint("DrawAllocation") StaticLayout myStaticLayout = new StaticLayout(result, tp, getWidth(), layout.getAlignment(), getLineSpacingMultiplier(), getLineSpacingExtra(), false);
myStaticLayout.draw(canvas);
}
private void drawTextWithoutSuffix(Canvas canvas) {
//暂时不考虑收起的状态
Layout layout = getLayout();
Paint paint = layout.getPaint();
paint.setTextSize(textSize);
TextPaint tp = getPaint();
tp.setColor(getCurrentTextColor()); // 此处需要重新赋值,由于日夜间模式的色值最终是在super.onDraw 中设置给paint,此处没有调用super,因此手动设置色值。
@SuppressLint("DrawAllocation") StaticLayout myStaticLayout = new StaticLayout(originalData, tp, getWidth(), layout.getAlignment(), getLineSpacingMultiplier(), getLineSpacingExtra(), false);
myStaticLayout.draw(canvas);
}
private SpannableStringBuilder addSuffix(CharSequence text) {
SpannableStringBuilder processedText = new SpannableStringBuilder(text);
processedText.append("... ");
processedText.append(suffix);
return processedText;
}
public int getContentTextSize() {
return sp2px(17);
}
public int getSuffixTextSize() {
return sp2px(14);
}
private int sp2px(float sp) {
return (int) TypedValue.applyDimension(COMPLEX_UNIT_SP, sp, getResources().getDisplayMetrics());
}
public void setValue(String data) {
setMaxLines(maxLines);
setEllipsize(TextUtils.TruncateAt.END);
setText(getSpannableStringBuilder(data));
invalidate();
}
private SpannableStringBuilder getSpannableStringBuilder(String summary) {
SpannableStringBuilder strBuilder = new SpannableStringBuilder(summary);
ColorStateList contentColorStateList = ColorStateList.valueOf(textColor);
TextAppearanceSpan contentSpan = new TextAppearanceSpan("default", Typeface.NORMAL,
textSize,
contentColorStateList,
null);
strBuilder.setSpan(contentSpan, 0, strBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
if (isClickable) {
addSuffix(strBuilder);
}
return strBuilder;
}
private void addSuffix(SpannableStringBuilder strBuilder) {
SpannableString suffix = new SpannableString(SUFFIX);
TextAppearanceSpan suffixSpan = new TextAppearanceSpan("default", Typeface.NORMAL,
suffixTextSize,
ColorStateList.valueOf(cornerTextColor),
null);
suffix.setSpan(suffixSpan, 0, suffix.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
strBuilder.append(" ");
strBuilder.append(suffix);
setOnClickListener((view)->{
Log.e(TAG, "addSuffix: " );
});
}
public void setViewClickable(Boolean apply) {
this.isClickable = apply;
}
public void setViewTextColor(Integer apply) {
if (apply != 0) {
textColor = apply;
}
}
public void setViewTextSize(Integer apply) {
textSize = sp2px(apply);
}
public void setViewFontStyle(String apply) {
}
public void setViewCornerText(String apply) {
this.isClickable = !TextUtils.isEmpty(apply);
SUFFIX = apply;
}
public void setViewCornerTextColor(Integer apply) {
if (apply != 0) {
cornerTextColor = apply;
// Log.e(TAG, "setViewCornerTextColor: " +cornerTextColor);
}
}
public void setViewCornerTextSize(Integer apply) {
suffixTextSize = sp2px(apply);
}
public float getViewCornerTextSize() {
return suffixTextSize;
}
public void setMaxLines(Integer apply) {
if (apply > 0) {
maxLines = apply;
}
}
@Override
public boolean isClickable() {
return isClickable;
}
public int getTextColor() {
return textColor;
}
public int getCornerTextColor() {
return cornerTextColor;
}
@Override
public float getTextSize() {
return textSize;
}
@Override
public int getMaxLines() {
return maxLines;
}
public String getSUFFIX() {
return SUFFIX;
}
public void setViewShowCornerAlways(Boolean apply) {
this.cornerAlwaysShow = apply != null && apply;
}
public void setOriginalData(String data) {
this.originalData =data;
}
}
package com.yidian.common.widget.chameleon;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Typeface;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.ClickableSpan;
import android.text.style.TextAppearanceSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import com.yidian.common.R;
import com.yidian.nightmode.widget.YdFrameLayout;
import com.yidian.nightmode_basic_widget.helper.NMBgResHelper;
import com.yidian.nightmode_basic_widget.helper.NMTextColorResHelper;
import com.yidian.nightmode_basic_widget.parser.value.NMColorResValueParser;
public class SubwayRichTextViewGroup extends YdFrameLayout implements NMTextColorResHelper.IResSetter, NMBgResHelper.IResSetter {
private static final String TAG = "SubwayRichTextViewGroup";
private SubwayRichTextView richTextView;
public SubwayRichTextViewGroup(Context context) {
super(context);
init(context, null);
}
public SubwayRichTextViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public SubwayRichTextViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
public void init(Context context, AttributeSet attrs) {
richTextView = new SubwayRichTextView(context);
LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);
richTextView.setLayoutParams(layoutParams);
addView(richTextView);
}
private String data;
public void setValue(String data) {
this.data = data;
richTextView.setMaxLines( richTextView.getMaxLines());
richTextView.setEllipsize(TextUtils.TruncateAt.END);
setContent(data);
}
private void setContent(String data) {
richTextView.setOriginalData(data);
SpannableStringBuilder strBuilder = new SpannableStringBuilder(data);
ColorStateList contentColorStateList;
contentColorStateList = ColorStateList.valueOf(richTextView.getTextColor());
TextAppearanceSpan contentSpan = new TextAppearanceSpan("default", Typeface.NORMAL,
(int) richTextView.getTextSize(),
contentColorStateList,
null);
strBuilder.setSpan(contentSpan, 0, strBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
if (richTextView.isClickable()) {
addSuffix(strBuilder);
}
richTextView.setText(strBuilder);
}
private void addSuffix(SpannableStringBuilder strBuilder) {
SpannableString suffix = new SpannableString(richTextView.getSUFFIX());
TextAppearanceSpan suffixSpan = new TextAppearanceSpan("default", Typeface.NORMAL,
(int) richTextView.getViewCornerTextSize(),
ColorStateList.valueOf(richTextView.getCornerTextColor()),
null);
suffix.setSpan(suffixSpan, 0, suffix.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ExpandSpan clickSpan = new ExpandSpan(richTextView.getCornerTextColor());
suffix.setSpan(clickSpan,0, suffix.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
richTextView.setSuffix(suffix);
strBuilder.append(" ");
strBuilder.append(suffix);
clickSpan.setOnRichClickListener(() -> {
Log.e(TAG, "addSuffix: 折叠 展开 " );
});
}
public void setViewClickable(Boolean apply) {
richTextView.setViewClickable(apply);
}
public void setViewTextColor(Integer apply) {
if (apply != 0) {
richTextView.setViewTextColor(apply);
}
}
public void setViewTextSize(Integer apply) {
richTextView.setViewTextSize(apply);
}
public void setViewFontStyle(String apply) {
}
public void setViewCornerText(String apply) {
richTextView.setViewCornerText(apply);
}
public void setViewCornerTextColor(Integer apply) {
richTextView.setViewCornerTextColor(apply);
}
public void setViewCornerTextSize(Integer apply) {
richTextView.setViewCornerTextSize(apply);
}
public void setMaxLines(Integer apply) {
richTextView.setMaxLines(apply);
}
private void setViewShowCornerAlways(Boolean apply) {
richTextView.setViewShowCornerAlways(apply);
}
NMColorResValueParser nmColorResValueParser;
String valueStr;
@Override
public void setTextColorResValue(String s) {
if (!TextUtils.isEmpty(s) && s.contains("@")) {
this.valueStr = s;
nmColorResValueParser = new NMColorResValueParser();
setViewTextColor(nmColorResValueParser.apply(valueStr));
}
}
@Override
public void setBgResValue(String s, String s1, String s2) {
}
@Override
public void setTheme(Resources.Theme themeId) {
super.setTheme(themeId);
if (nmColorResValueParser != null) {
setViewTextColor(nmColorResValueParser.apply(valueStr));
setValue(data);
}
}
public void setShowCornerAlways(Boolean apply) {
setViewShowCornerAlways(apply);
}
private static class ExpandSpan extends ClickableSpan {
private int color;
private RichClickListener listener;
public ExpandSpan(int color) {
this.color = color;
}
public void setOnRichClickListener(RichClickListener l){
listener =l;
}
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(color);
ds.setUnderlineText(false);
}
@Override
public void onClick(@NonNull View widget) {
if (widget instanceof TextView) {
((TextView) widget).setHighlightColor(Color.TRANSPARENT);
if (listener!=null){
listener.onClick();
}
}
}
}
interface RichClickListener{
void onClick();
}
}
package com.yidian.subway.wxapi
import com.umeng.socialize.weixin.view.WXCallbackActivity
class WXEntryActivity: WXCallbackActivity()
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator">
<translate
android:duration="@android:integer/config_shortAnimTime"
android:fromXDelta="100.0%p"
android:toXDelta="0.0" />
</set>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator">
<translate
android:duration="@android:integer/config_shortAnimTime"
android:fromXDelta="0.0"
android:toXDelta="100.0%p" />
</set>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/loading_02"
android:duration="200"/>
<item android:drawable="@drawable/loading_03"
android:duration="200"/>
<item android:drawable="@drawable/loading_01"
android:duration="200"/>
</animation-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval" >
<solid android:color="@color/white" />
</shape>
</item>
<item
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp">
<shape android:shape="oval">
<solid android:color="@color/authorPointColor" />
</shape>
</item>
</layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape= "oval"
android:useLevel= "false">
<solid android:color="@color/white"/>
<stroke android:width= "1dp" android:color= "@color/btn_cancel_color"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/mainYellowColor" />
<corners android:radius="20dp"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#B0B2BA" />
<corners android:radius="4dp"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/mainYellowColor" />
<corners android:radius="24dp"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#E6303746" />
<corners android:radius="24dp"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<corners android:radius="20dp"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape= "oval"
android:useLevel= "false">
<solid android:color="@color/white"/>
<stroke android:width= "2dp" android:color= "@color/white"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<corners android:radius="6dp"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<corners android:radius="14dp"/>
<stroke android:width="0.5dp" android:color="@color/strokeGrayColor" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape= "oval"
android:useLevel= "false">
<solid android:color="@color/white"/>
<stroke android:width= "2dp" android:color= "@color/mainYellowColor"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/mainYellowColor" />
<corners android:radius="4dp"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/mainYellowColor" />
<corners android:radius="14dp"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/icon_select_on" android:state_checked="true" />
<item android:drawable="@mipmap/icon_select_off" android:state_checked="false" />
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/secondTabSelectColor" android:state_checked="true" />
<item android:color="@color/secondTabUnSelectColor" android:state_checked="false" />
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.LoginActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/et_username"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_margin="20dp"
android:hint="请输入账号"
android:text="18900000000"
android:inputType="phone"
android:textSize="18sp"/>
<EditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_margin="20dp"
android:text="123456"
android:hint="请输入密码"
android:textSize="18sp"/>
<Button
android:id="@+id/btn_login"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_margin="20dp"
android:textSize="18sp"
android:text="登录"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="50dp"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/lly_wechat"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:gravity="center">
<de.hdodenhof.circleimageview.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:src="@mipmap/ic_launcher_round"
app:civ_border_width="2dp"
app:civ_border_color="#FF000000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textSize="16sp"
android:text="微信"/>
</LinearLayout>
<LinearLayout
android:id="@+id/lly_qq"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:gravity="center">
<de.hdodenhof.circleimageview.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:src="@mipmap/ic_launcher_round"
app:civ_border_width="2dp"
app:civ_border_color="#FF000000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textSize="16sp"
android:text="QQ"/>
</LinearLayout>
<LinearLayout
android:id="@+id/lly_sina"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:gravity="center">
<de.hdodenhof.circleimageview.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:src="@mipmap/ic_launcher_round"
app:civ_border_width="2dp"
app:civ_border_color="#FF000000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textSize="16sp"
android:text="微博"/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.OneKeyLoginActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="150dp"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@mipmap/ic_launcher"/>
<TextView
android:id="@+id/tv_phoneNo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textColor="#000000"
android:textSize="22sp"
android:text="189****0000" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#a9a9a9"
android:textSize="12sp"
android:text="中国移动提供认证服务" />
<Button
android:id="@+id/btn_oneKeyLogin"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_margin="20dp"
android:background="#1e90ff"
android:textColor="#ffffff"
android:textSize="16sp"
android:text="本机号码一键登录"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#a9a9a9"
android:textSize="14sp"
android:text="不是此号码?使用其他账号" />
<TextView
android:id="@+id/tv_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:textColor="#1e90ff"
android:textSize="14sp"
android:text="登录" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<com.yidian.nightmode.widget.YdLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="MissingDefaultResource">
<com.yidian.nightmode.widget.YdLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="47.5dp"
android:layout_marginRight="47.5dp"
android:orientation="vertical"
android:background="@drawable/bg_white_radio">
<com.yidian.nightmode.widget.YdTextView
android:id="@+id/tv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:gravity="center"
android:textSize="17sp"
android:textColor="@color/black"/>
<com.yidian.nightmode.widget.YdView
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/cardCutLineColor"/>
<com.yidian.nightmode.widget.YdLinearLayout
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal">
<com.yidian.nightmode.widget.YdTextView
android:id="@+id/tv_delete"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:textSize="16sp"
android:textColor="@color/mainRedColor"
android:gravity="center"
android:text="删除"/>
<com.yidian.nightmode.widget.YdView
android:layout_width="0.5dp"
android:layout_height="match_parent"
android:background="@color/cardCutLineColor"/>
<com.yidian.nightmode.widget.YdTextView
android:id="@+id/tv_cancel"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:textSize="16sp"
android:textColor="@color/dialogCancelColor"
android:gravity="center"
android:text="取消"/>
</com.yidian.nightmode.widget.YdLinearLayout>
</com.yidian.nightmode.widget.YdLinearLayout>
</com.yidian.nightmode.widget.YdLinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rv_group"
android:background="@drawable/bg_white_radio"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<?xml version="1.0" encoding="utf-8"?>
<com.yidian.nightmode.widget.YdLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<com.yidian.nightmode.widget.YdCheckedBox
android:id="@+id/cb_checked"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginStart="10dp"
style="@style/checkboxBg"
android:visibility="gone"/>
<com.yidian.nightmode.widget.YdRelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="@drawable/bg_white_radio">
<com.yidian.nightmode.widget.YdImageView
android:layout_width="145dp"
android:layout_height="45dp"
android:background="@mipmap/card_yellow_bg"/>
<com.yidian.nightmode.widget.YdRelativeLayout
android:id="@+id/rly_cardHead"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginStart="17dp">
<com.yidian.nightmode.widget.YdRelativeLayout
android:id="@+id/fly_data"
android:layout_width="36dp"
android:layout_height="30dp"
android:background="@mipmap/calendar_icon">
<com.yidian.nightmode.widget.YdTextView
android:id="@+id/tv_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp"
android:textSize="12sp"
android:textColor="@color/black"
android:textStyle="bold"
android:text="12/08"/>
</com.yidian.nightmode.widget.YdRelativeLayout>
<com.yidian.nightmode.widget.YdLinearLayout
android:id="@+id/lly_dailyTheme"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_centerVertical="true"
android:gravity="center_vertical"
android:layout_toEndOf="@id/fly_data"
android:layout_marginStart="10dp">
<com.yidian.nightmode.widget.YdTextView
android:id="@+id/tv_dailyTheme"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="16sp"
android:textColor="@color/mainBlackColor"
android:text="娱乐最前线"/>
<com.yidian.nightmode.widget.YdImageView
android:layout_width="13dp"
android:layout_height="15dp"
android:layout_marginStart="2dp"
android:background="@mipmap/right_arrows_black"/>
</com.yidian.nightmode.widget.YdLinearLayout>
<com.yidian.nightmode.widget.YdImageView
android:id="@+id/iv_close"
android:layout_width="21dp"
android:layout_height="21dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="14dp"
android:background="@mipmap/close"/>
<com.yidian.nightmode.widget.YdTextView
android:id="@+id/tv_subscribe"
android:layout_width="56dp"
android:layout_height="28dp"
android:orientation="horizontal"
android:layout_centerVertical="true"
android:layout_toStartOf="@id/iv_close"
android:layout_marginEnd="10dp"
android:gravity="center"
android:background="@drawable/bg_white_subscribe_radio"
android:textSize="14sp"
android:textColor="@color/secondTabSelectColor"
android:text="+ 订阅"/>
</com.yidian.nightmode.widget.YdRelativeLayout>
<com.yidian.nightmode.widget.YdLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/rly_cardHead"
android:orientation="vertical">
<com.yidian.nightmode.widget.YdLinearLayout
android:id="@+id/lly_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="14dp"
android:layout_marginEnd="14dp"
android:orientation="vertical">
<com.yidian.nightmode.widget.YdTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:textSize="17sp"
android:textColor="@color/mainBlackColor"
android:text="1、被刘德华邀请演他的夫人 贾玲:咱两的事你说了算"/>
<com.yidian.nightmode.widget.YdTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:textSize="17sp"
android:textColor="@color/mainBlackColor"
android:text="2、被刘德华邀请演他的夫人 贾玲:咱两的事你说了算"/>
<com.yidian.nightmode.widget.YdTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:textSize="17sp"
android:textColor="@color/mainBlackColor"
android:text="3、被刘德华邀请演他的夫人 贾玲:咱两的事你说了算"/>
<com.yidian.nightmode.widget.YdTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:textSize="17sp"
android:textColor="@color/mainBlackColor"
android:text="4、被刘德华邀请演他的夫人 贾玲:咱两的事你说了算"/>
<com.yidian.nightmode.widget.YdTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:textSize="17sp"
android:textColor="@color/mainBlackColor"
android:text="5、被刘德华邀请演他的夫人 贾玲:咱两的事你说了算"/>
</com.yidian.nightmode.widget.YdLinearLayout>
<com.yidian.nightmode.widget.YdRelativeLayout
android:id="@+id/rly_showMore"
android:layout_width="match_parent"
android:layout_height="44dp">
<com.yidian.nightmode.widget.YdView
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_marginStart="14dp"
android:layout_marginEnd="14dp"
android:background="@color/cardCutLineColor"/>
<com.yidian.nightmode.widget.YdLinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_centerInParent="true"
android:gravity="center">
<com.yidian.nightmode.widget.YdTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:textColor="@color/ashBlueColor"
android:text="展开更多"/>
<com.yidian.nightmode.widget.YdImageView
android:layout_width="25dp"
android:layout_height="20dp"
android:background="@mipmap/down_arrows"/>
</com.yidian.nightmode.widget.YdLinearLayout>
</com.yidian.nightmode.widget.YdRelativeLayout>
</com.yidian.nightmode.widget.YdLinearLayout>
</com.yidian.nightmode.widget.YdRelativeLayout>
</com.yidian.nightmode.widget.YdLinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<com.yidian.nightmode.widget.YdRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:background="@color/mainBgColor">
<com.yidian.nightmode.widget.YdLinearLayout
android:id="@+id/lly_subscribe"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_alignParentEnd="true"
android:orientation="vertical"
android:gravity="center"
android:background="@drawable/bg_white_radio">
<com.yidian.nightmode.widget.YdView
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/mainBlackColor"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"/>
<com.yidian.nightmode.widget.YdView
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/mainBlackColor"
android:layout_marginTop="2dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"/>
<com.yidian.nightmode.widget.YdTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp"
android:textColor="@color/mainBlackColor"
android:text="订阅日报"
android:textSize="17sp"
android:textStyle="bold"/>
<com.yidian.nightmode.widget.YdView
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/mainBlackColor"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"/>
<com.yidian.nightmode.widget.YdImageView
android:layout_width="64dp"
android:layout_height="24dp"
android:layout_marginTop="6.5dp"
android:background="@mipmap/news_icon"/>
</com.yidian.nightmode.widget.YdLinearLayout>
<com.yidian.nightmode.widget.YdRelativeLayout
android:id="@+id/rly_newsBroadcast"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_toStartOf="@id/lly_subscribe"
android:layout_marginEnd="16dp"
android:background="@drawable/bg_white_radio">
<com.yidian.nightmode.widget.YdImageView
android:id="@+id/iv_loudspeakerIcon"
android:layout_width="60dp"
android:layout_height="54.5dp"
android:layout_marginStart="12.5dp"
android:layout_centerVertical="true"
android:background="@mipmap/loudspeaker_icon"/>
<com.yidian.nightmode.widget.YdLinearLayout
android:layout_width="wrap_content"
android:layout_height="35dp"
android:orientation="horizontal"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:layout_marginEnd="15dp"
android:gravity="center_vertical">
<com.yidian.nightmode.widget.YdImageView
android:layout_width="52dp"
android:layout_height="35dp"
android:layout_marginStart="12.5dp"
android:background="@mipmap/voice_icon"/>
<com.yidian.nightmode.widget.YdImageView
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="4dp"
android:background="@mipmap/voice_play_icon"/>
</com.yidian.nightmode.widget.YdLinearLayout>
<com.yidian.nightmode.widget.YdLinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/iv_loudspeakerIcon"
android:layout_marginStart="9.5dp"
android:orientation="vertical">
<com.yidian.nightmode.widget.YdTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/mainBlackColor"
android:text="要闻播报"
android:textSize="17sp"
android:textStyle="bold"/>
<com.yidian.nightmode.widget.YdTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:textColor="@color/ashGrayColor"
android:text="听新闻·知新闻"
android:textSize="12sp"/>
</com.yidian.nightmode.widget.YdLinearLayout>
</com.yidian.nightmode.widget.YdRelativeLayout>
</com.yidian.nightmode.widget.YdRelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<com.yidian.nightmode.widget.YdFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp">
<com.yidian.nightmode.widget.YdTextView
android:id="@+id/tv_tab"
android:layout_width="56dp"
android:layout_height="28dp"
android:textSize="14sp"
android:gravity="center"/>
</com.yidian.nightmode.widget.YdFrameLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<com.yidian.nightmode.widget.YdFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.yidian.nightmode.widget.YdRecyclerView
android:id="@+id/rv_head"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"/>
</com.yidian.nightmode.widget.YdFrameLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<com.yidian.nightmode.widget.YdTextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:layout_marginBottom="66.5dp"
android:textColor="@color/ashGrayColor"
android:textSize="12sp"
android:gravity="center"
android:text="已显示全部内容"/>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="120dp">
<com.yidian.nightmode.widget.YdCheckedBox
android:id="@+id/cb_checked"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginStart="10dp"
style="@style/checkboxBg"
android:visibility="gone"/>
<com.yidian.nightmode.widget.YdLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv_itemHomeName"
android:textSize="16sp"
android:layout_marginStart="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/tv_itemHomeContent"
android:textSize="16sp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</com.yidian.nightmode.widget.YdLinearLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<com.yidian.nightmode.widget.YdFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.yidian.nightmode.widget.YdLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<com.yidian.nightmode.widget.YdCheckedBox
android:id="@+id/cb_checked"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginStart="10dp"
style="@style/checkboxBg"
android:visibility="gone"/>
<com.yidian.nightmode.widget.YdLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="@drawable/bg_white_radio">
<com.yidian.nightmode.widget.YdFrameLayout
android:id="@+id/fly_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<com.yidian.common.widget.YdMaxRecyclerView
android:id="@+id/rv_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.yidian.nightmode.widget.YdLinearLayout>
</com.yidian.nightmode.widget.YdLinearLayout>
<com.yidian.nightmode.widget.YdView
android:id="@+id/v_manage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"/>
</com.yidian.nightmode.widget.YdFrameLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<com.yidian.nightmode.widget.YdLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="80dp"
android:layout_height="105dp"
android:orientation="vertical"
android:gravity="center">
<com.yidian.nightmode.widget.YdRelativeLayout
android:layout_width="wrap_content"
android:layout_height="53dp">
<com.yidian.nightmode.widget.YdRelativeLayout
android:layout_width="48dp"
android:layout_height="48dp"
android:background="@drawable/bg_yellow_circle">
<com.yidian.nightmode.widget.YdImageView
android:id="@+id/iv_add"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_centerInParent="true"
android:background="@mipmap/add_yellow"/>
<com.yidian.nightmode.widget.YdImageView
android:id="@+id/iv_more"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_centerInParent="true"
android:background="@mipmap/more_yellow"/>
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/iv_icon"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_centerInParent="true"/>
</com.yidian.nightmode.widget.YdRelativeLayout>
<com.yidian.nightmode.widget.YdImageView
android:id="@+id/iv_point"
android:layout_width="11dp"
android:layout_height="11dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/author_point"/>
</com.yidian.nightmode.widget.YdRelativeLayout>
<com.yidian.nightmode.widget.YdTextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="7dp"
android:textSize="12sp"
android:maxLines="1"
android:maxEms="5"
android:ellipsize="end"
android:textColor="@color/subscribeHeadColor"/>
</com.yidian.nightmode.widget.YdLinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<com.yidian.nightmode.widget.YdRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="105dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="@drawable/bg_white_radio">
<com.yidian.nightmode.widget.YdRecyclerView
android:id="@+id/rv_subscribe"
android:layout_width="wrap_content"
android:layout_height="match_parent"/>
</com.yidian.nightmode.widget.YdRelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<com.yidian.nightmode.widget.YdFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/fly_root"/>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="68dp">
<ImageView
android:id="@+id/iv_loading"
android:src="@drawable/anim_loading"
android:layout_gravity="center"
android:layout_width="40dp"
android:layout_height="8dp"/>
</FrameLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="102dp">
<ImageView
android:id="@+id/iv_loading"
android:src="@drawable/anim_loading"
android:layout_gravity="center"
android:layout_width="40dp"
android:layout_height="8dp"/>
<com.yidian.nightmode.widget.YdTextView
android:id="@+id/tv_loading"
android:layout_marginTop="18dp"
android:layout_gravity="center"
android:text="正在努力加载"
android:textSize="12sp"
android:textColor="@color/footer_loading_gray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</FrameLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#00000000"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/add_panel_ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
</LinearLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<com.yidian.nightmode.widget.YdLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="30dp"
android:paddingRight="30dp"
android:gravity="center"
android:background="@drawable/bg_refresh_toast_radio">
<com.yidian.nightmode.widget.YdTextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:textStyle="bold"
android:textSize="14sp"
android:textColor="@color/refreshToastColor"/>
</com.yidian.nightmode.widget.YdLinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<com.yidian.nightmode.widget.YdLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:gravity="center"
android:background="@drawable/bg_toast_radio">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/iv_icon"
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_marginEnd="8dp"
android:scaleType="centerCrop"
android:visibility="gone"/>
<com.yidian.nightmode.widget.YdTextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="13dp"
android:layout_marginBottom="13dp"
android:textSize="16sp"
android:textColor="@color/white"/>
</com.yidian.nightmode.widget.YdLinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="white">#ffffff</color>
<color name="black">#000000</color>
<color name="transparent">#00000000</color>
<color name="mainBgColor">#f4f5fa</color>
<color name="mainYellowColor">#fecd05</color>
<color name="mainBlackColor">#191F2C</color>
<color name="firstTabColor">#19202C</color>
<color name="secondTabSelectColor">#231F0E</color>
<color name="secondTabUnSelectColor">#5A5A5A</color>
<color name="hintColor">#B0B2BA</color>
<color name="ashGrayColor">#909DA3</color>
<color name="strokeGrayColor">#D7DBE1</color>
<color name="cardCutLineColor">#EFF0F6</color>
<color name="ashBlueColor">#657BA9</color>
<color name="btn_cancel_color">#EFF1F3</color>
<color name="subscribeHeadColor">#2C2E30</color>
<color name="feedbackHintColor">#A8ABB1</color>
<color name="feedbackCutLineColor">#EEEEEE</color>
<color name="mainRedColor">#FA4A3E</color>
<color name="dialogCancelColor">#8C8F96</color>
<color name="authorPointColor">#00D5A8</color>
<color name="refreshToastColor">#333333</color>
<color name="btnDisagreeColor">#A8ABB3</color>
<color name="lightBlueColor">#1157F4</color>
<color name="black_919191">#919191</color>
<color name="footer_loading_gray">#a8abb1</color>
<color name="commentSendBtn">#A7A69f</color>
</resources>
<resources></resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="right_anim_style">
<item name="android:activityOpenEnterAnimation">@anim/slide_right_in</item>
<item name="android:activityCloseExitAnimation">@anim/slide_right_out</item>
</style>
<style name="checkboxBg" parent="@android:style/Widget.CompoundButton.CheckBox">
<item name="android:button">@drawable/checkbox_bg</item>
</style>
<style name="normal_dialog" parent="android:style/Theme.Dialog">
<item name="android:windowFrame">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
<style name="update_dialog" parent="android:style/Theme.Dialog">
<item name="android:windowFrame">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:backgroundDimAmount">0.42</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
<style name="AnimationActivity"><!--parent="@android:style/Animation.Activity">-->
<item name="android:activityOpenEnterAnimation">@anim/slide_right_in</item>
<item name="android:activityCloseExitAnimation">@anim/slide_right_out</item>
<item name="android:taskToFrontEnterAnimation">@null</item>
</style>
<style name="YDSubwayCommonTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowAnimationStyle">@style/AnimationActivity</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowDisablePreview">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowEnterAnimation">@anim/slide_right_in</item>
<item name="android:windowExitAnimation">@anim/slide_right_out</item>
<item name="android:icon">@android:color/transparent</item>
</style>
<style name="subway_theme_day" parent="YDSubwayCommonTheme">
<item name="black_first">#222222</item>
<item name="main_bg">#ffffff</item>
<item name="title_text">#222222</item>
<item name="summary_text">#5a5a5a</item>
<item name="subTitle_dark_text">#919191</item>
<item name="subTitle_light_text">#bfbfbf</item>
<item name="view_divider_bg">#e6e6e6</item>
<item name="view_divider_dark_bg">#d9d9d9</item>
<item name="view_divider_wide_bg">#f7f7f7</item>
</style>
<style name="subway_theme_night" parent="YDSubwayCommonTheme">
<item name="black_first">#bababa</item>
<item name="main_bg">#333333</item>
<item name="title_text">#222222</item>
<item name="summary_text">#919191</item>
<item name="subTitle_dark_text">#888888</item>
<item name="subTitle_light_text">#666666</item>
<item name="view_divider_bg">#404040</item>
<item name="view_divider_dark_bg">#4c4c4c</item>
<item name="view_divider_wide_bg">#222222</item>
</style>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-files-path name="umeng_cache" path="umeng_cache/"/>
<external-files-path name="opensdk_external" path="Images/tmp"/>
<root-path name="opensdk_root" path=""/>
<external-cache-path name="video_cache" path="video_cache/"/>
</paths>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
\ No newline at end of file
package com.yidian.common
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment