Commit 607833f5 authored by shiyl's avatar shiyl

Merge branch 'feature/dev_order' of...

Merge branch 'feature/dev_order' of https://git.yidian-inc.com:8021/bp/ShenghuoquanBusiness into feature/dev_order

# Conflicts:
#	Components/newscontent/src/main/java/com/yidian/shenghuoquan/newscontent/app/NewsContentApplication.kt
#	Components/newscontent/src/main/java/com/yidian/shenghuoquan/newscontent/service/CommentService.kt
#	Components/newscontent/src/main/java/com/yidian/shenghuoquan/newscontent/service/DeepLinkService.kt
#	Components/newscontent/src/main/java/com/yidian/shenghuoquan/newscontent/service/RequestService.kt
#	Components/newscontent/src/main/java/com/yidian/shenghuoquan/newscontent/service/UniversalService.kt
#	Components/newscontent/src/main/java/com/yidian/shenghuoquan/newscontent/ui/CommentWebFragment.kt
#	Components/newscontent/src/main/java/com/yidian/shenghuoquan/newscontent/ui/DeepLinkActivity.kt
#	Components/newscontent/src/main/java/com/yidian/shenghuoquan/newscontent/ui/LifeAccountEnterpriseCertificationActivity.kt
#	Components/newscontent/src/main/java/com/yidian/shenghuoquan/newscontent/ui/NewsContentActivity.kt
#	Components/newscontent/src/main/java/com/yidian/shenghuoquan/newscontent/ui/ProductSupportActivity.kt
#	Components/newscontent/src/main/java/com/yidian/shenghuoquan/newscontent/ui/alive/AliveTestActivity.kt
#	Components/newscontent/src/main/java/com/yidian/shenghuoquan/newscontent/ui/dialog/ProtocolDialog.kt
#	Components/newscontent/src/main/java/com/yidian/shenghuoquan/newscontent/ui/dialog/ProtocolHintDialog.kt
#	Components/newscontent/src/main/java/com/yidian/shenghuoquan/newscontent/ui/dialog/ShareDialog.kt
#	Components/newscontent/src/main/java/com/yidian/shenghuoquan/newscontent/ui/dialog/ShareImageDialog.kt
#	Components/newscontent/src/main/java/com/yidian/shenghuoquan/newscontent/ui/dialog/SharePosterDialog.kt
#	Components/newscontent/src/main/java/com/yidian/shenghuoquan/newscontent/utils/AccountUtil.kt
parents 9a114c0d 5b9af99f
...@@ -3,33 +3,6 @@ ...@@ -3,33 +3,6 @@
package="com.yidian.shenghuoquan.newscontent"> package="com.yidian.shenghuoquan.newscontent">
<application> <application>
<activity android:name=".ui.DeepLinkActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="link_news"
android:scheme="ydsubway" />
</intent-filter>
</activity>
<activity
android:name=".ui.NewsContentActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize|uiMode" />
<service
android:name=".audio.AudioService"
android:enabled="true"
android:exported="true" />
<activity
android:name=".ui.alive.AliveTestActivity"
android:theme="@style/Transparent" />
<activity
android:name=".ui.idcard.IDCardTestActivity"
android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.auth.LifeAccountEnterpriseAuthCompleteActivity" android:name=".ui.auth.LifeAccountEnterpriseAuthCompleteActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
...@@ -39,60 +12,38 @@ ...@@ -39,60 +12,38 @@
<activity <activity
android:name=".ui.auth.LifeAccountCreateCompleteActivity" android:name=".ui.auth.LifeAccountCreateCompleteActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity
android:name=".ui.idcard.IDCardResultActivity"
android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.ProtocolActivity" android:name=".ui.ProtocolActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity
android:name=".ui.ProductSupportActivity"
android:theme="@style/Transparent" />
<activity android:name=".ui.LoginLifeCircleActivity" /> <activity android:name=".ui.LoginLifeCircleActivity" />
<activity <activity
android:name=".ui.store.StoreManagementActivity" android:name=".ui.store.StoreManagementActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.store.EditStoreActivity" android:name=".ui.store.EditStoreActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.store.SelectAddressActivity" android:name=".ui.store.SelectAddressActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.store.SearchAddActivity" android:name=".ui.store.SearchAddActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.auth.LifeAccountIdentityActivity" android:name=".ui.auth.LifeAccountIdentityActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.auth.LifeAccountAuthActivity" android:name=".ui.auth.LifeAccountAuthActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity
android:name=".ui.LifeAccountEnterpriseCertificationActivity"
android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.auth.LifeAccountCreateActivity" android:name=".ui.auth.LifeAccountCreateActivity"
android:theme="@style/Transparent" android:theme="@style/Transparent"
android:windowSoftInputMode="stateHidden|adjustResize" /> android:windowSoftInputMode="stateHidden|adjustResize" />
<activity <activity
android:name=".ui.auth.LifeAccountPersonalAuthActivity" android:name=".ui.auth.LifeAccountPersonalAuthActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.auth.LifeAccountEnterpriseAuthActivity" android:name=".ui.auth.LifeAccountEnterpriseAuthActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity <activity
android:name=".personnel.ui.MyStaffActivity" android:name=".personnel.ui.MyStaffActivity"
android:launchMode="singleTask" android:launchMode="singleTask"
...@@ -115,20 +66,16 @@ ...@@ -115,20 +66,16 @@
<activity <activity
android:name=".ui.setting.SystemSettingActivity" android:name=".ui.setting.SystemSettingActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.center.MerchantCenterActivity" android:name=".ui.center.MerchantCenterActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.center.MerchantInfoActivity" android:name=".ui.center.MerchantInfoActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.center.LifeAccountModifyNameActivity" android:name=".ui.center.LifeAccountModifyNameActivity"
android:theme="@style/Transparent" android:theme="@style/Transparent"
android:windowSoftInputMode="stateVisible" /> android:windowSoftInputMode="stateVisible" />
<activity <activity
android:name=".ui.center.MerchantAuthInfoActivity" android:name=".ui.center.MerchantAuthInfoActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
...@@ -146,7 +93,6 @@ ...@@ -146,7 +93,6 @@
android:name=".ui.center.MerchantAuthManagementActivity" android:name=".ui.center.MerchantAuthManagementActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" /> android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
<activity android:name=".ui.setting.FeedbackActivity" /> <activity android:name=".ui.setting.FeedbackActivity" />
</application> </application>
</manifest> </manifest>
\ No newline at end of file
package com.yidian.shenghuoquan.newscontent.adapter
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.yidian.bcommon.cardutils.adapter.OnItemClickListener
import com.yidian.bcommon.utils.ViewHolderUtil.Companion.createItemView
import com.yidian.shenghuoquan.newscontent.R
import kotlinx.android.extensions.LayoutContainer
class FeedbackDetailAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val dataList: ArrayList<String> by lazy { ArrayList<String>() }
private lateinit var mOnItemClickListener: OnItemClickListener<String>
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return ViewHolder(createItemView(parent, R.layout.item_feedback_detail))
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
holder as ViewHolder
val tvContent = holder.itemView.findViewById<TextView>(R.id.tv_content)
holder.setData(dataList[position], tvContent)
holder.itemView.setOnClickListener {
mOnItemClickListener.onClick(it, position, dataList[position])
}
}
fun update(newData: ArrayList<String>) {
newData.let {
dataList.clear()
dataList.addAll(it)
notifyDataSetChanged()
}
}
override fun getItemCount(): Int {
return dataList.size
}
fun setOnItemClickListener(onItemClickListener: OnItemClickListener<String>) {
mOnItemClickListener = onItemClickListener
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), LayoutContainer {
override val containerView: View
get() = itemView
fun setData(content: String, tvContent: TextView) {
tvContent.text = content
}
}
}
package com.yidian.shenghuoquan.newscontent.adapter
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.yidian.bcommon.cardutils.adapter.OnItemClickListener
import com.yidian.bcommon.utils.ViewHolderUtil.Companion.createItemView
import com.yidian.shenghuoquan.newscontent.R
import com.yidian.shenghuoquan.newscontent.bean.SharePlatformBean
import kotlinx.android.extensions.LayoutContainer
class ShareAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>() {
companion object{
const val normalType = 0
const val headType = -1
const val footType = -2
}
private val dataList: ArrayList<SharePlatformBean> by lazy { ArrayList<SharePlatformBean>() }
private lateinit var mOnItemClickListener: OnItemClickListener<SharePlatformBean>
override fun getItemViewType(position: Int): Int {
return dataList[position].viewType
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when(viewType){
headType -> ViewHolder(createItemView(parent, R.layout.item_share_card))
footType -> ViewHolder(createItemView(parent, R.layout.item_share_link))
else -> ViewHolder(createItemView(parent, R.layout.item_share_platform))
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
holder as ViewHolder
holder.setData(dataList[position], holder)
holder.itemView.setOnClickListener{
mOnItemClickListener.onClick(it, position, dataList[position])
}
}
fun update(newData: ArrayList<SharePlatformBean>){
newData.let {
dataList.clear()
dataList.addAll(it)
notifyDataSetChanged()
}
}
override fun getItemCount(): Int {
return dataList.size
}
fun setOnItemClickListener(onItemClickListener: OnItemClickListener<SharePlatformBean>) {
mOnItemClickListener = onItemClickListener
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), LayoutContainer {
override val containerView: View
get() = itemView
fun setData(sharePlatformBean: SharePlatformBean, holder: ViewHolder) {
holder.itemView.findViewById<ImageView>(R.id.iv_platform).setBackgroundResource(sharePlatformBean.imageId)
holder.itemView.findViewById<TextView>(R.id.tv_platform).text = sharePlatformBean.name
}
}
}
...@@ -8,7 +8,7 @@ import androidx.recyclerview.widget.RecyclerView ...@@ -8,7 +8,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.yidian.shenghuoquan.newscontent.R import com.yidian.shenghuoquan.newscontent.R
import com.yidian.shenghuoquan.newscontent.http.httpbean.GetShopListBean import com.yidian.shenghuoquan.newscontent.http.httpbean.GetShopListBean
import com.yidian.shenghuoquan.newscontent.ui.store.EditStoreActivity import com.yidian.shenghuoquan.newscontent.ui.store.EditStoreActivity
import com.yidian.shenghuoquan.newscontent.viewholder.StoreViewHolder import com.yidian.shenghuoquan.newscontent.ui.store.viewholder.StoreViewHolder
/** /**
* 门店管理列表的adapter * 门店管理列表的adapter
......
package com.yidian.shenghuoquan.newscontent.adapter
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.yidian.bcommon.utils.ViewHolderUtil.Companion.createItemView
import com.yidian.shenghuoquan.newscontent.R
import kotlinx.android.extensions.LayoutContainer
class UpdateVersionDesAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val dataList: ArrayList<String> by lazy { ArrayList<String>() }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return ViewHolder(createItemView(parent, R.layout.item_update_version_des))
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
holder as ViewHolder
holder.setData(dataList[position], holder)
}
override fun getItemCount(): Int {
return dataList.size
}
fun update(newData: ArrayList<String>) {
newData.let {
dataList.clear()
dataList.addAll(it)
notifyDataSetChanged()
}
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), LayoutContainer {
override val containerView: View
get() = itemView
fun setData(des: String, holder: ViewHolder) {
holder.itemView.findViewById<TextView>(R.id.tv_versionDes).text = des
}
}
}
package com.yidian.shenghuoquan.newscontent.adapter
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
class ViewPagerAdapter(fragmentManager: FragmentManager,
private val fragments: List<Fragment>) : FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
override fun getItem(index: Int): Fragment = fragments[index]
override fun getCount(): Int = fragments.size
}
\ No newline at end of file
package com.yidian.shenghuoquan.newscontent.audio
import android.media.MediaPlayer
import java.lang.ref.WeakReference
class AudioPlayerManager private constructor(): IAudioControl {
companion object {
val instance: AudioPlayerManager by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { AudioPlayerManager() }
const val STATUS_START = 0
const val STATUS_PAUSE = 1
const val STATUS_STOP = 2
}
private var isAutoPlay = false
private var singleLoop = false
private var onPrepare: (() -> Unit)? = null
private var prepareResult: ((Boolean, Long) -> Unit)? = null
private var onError: (() -> Unit)? = null
private var bufferUpdate: ((Int) -> Unit)? = null
private var onComplete: (() -> Unit)? = null
private var audioPlayer: MediaPlayer? = null
private var audioView:WeakReference<IAudioView>?=null
private val audioList = mutableListOf<String>()
private var currentIndex = 0
private var duration:Int = 0
private var currentStatus = STATUS_STOP
private val prepareListener = MediaPlayer.OnPreparedListener {
onPrepare?.invoke()
prepareResult?.invoke(true, it.duration.toLong())
}
private val errorListener = MediaPlayer.OnErrorListener { mr, what, extra ->
onError?.invoke()
return@OnErrorListener true
}
private val bufferListener = MediaPlayer.OnBufferingUpdateListener {mp,percent->
bufferUpdate?.invoke(percent)
}
private val completeListener = MediaPlayer.OnCompletionListener {
if (onComplete!=null){
onComplete?.invoke()
}else{
if (isAutoPlay){
next()
}
}
}
fun setAudioList(list:MutableList<String>,index:Int = 0){
currentIndex = index
audioList.clear()
audioList.addAll(list)
}
fun prepareAsync (url: String?=null, result: ((Boolean, Long) -> Unit)?=null) {
val realUrl = if (url.isNullOrEmpty()) {
if (currentIndex>=audioList.size) null else audioList[currentIndex]
} else url
if (realUrl.isNullOrEmpty()) {
result?.invoke(false,0)
return
}
prepareResult = result
if (audioPlayer == null) {
audioPlayer = MediaPlayer()
}
audioPlayer?.apply {
setDataSource(realUrl)
setOnPreparedListener(prepareListener)
setOnErrorListener(errorListener)
setOnBufferingUpdateListener(bufferListener)
setOnCompletionListener(completeListener)
prepareAsync()
}
}
override fun bindAudioView(view: IAudioView) {
audioView = WeakReference(view)
view.bindAudioControl(this)
}
override fun start(progress: Int,user:Boolean) {
if (audioPlayer==null || audioPlayer?.duration?:0==0) return
if (user) isAutoPlay = true
if (progress<0){
audioPlayer?.start()
return
}
val duration = (audioPlayer!!.duration *progress.toFloat()/100 +0.5f).toInt()
audioPlayer?.seekTo(duration)
audioPlayer?.start()
}
override fun pause() {
audioPlayer?.pause()
}
override fun stop() {
audioPlayer?.stop()
}
override fun seekTo(progress: Int) {
val total = audioPlayer?.duration?:0
if (total == 0) return
audioPlayer?.seekTo((total * progress.toFloat()/total).toInt())
}
override fun isPlaying() :Boolean {
return audioPlayer!=null && audioPlayer!!.isPlaying
}
override fun next() {
if (audioPlayer?.isPlaying==true){
audioPlayer?.stop()
}
audioPlayer?.reset()
currentIndex++
if (currentIndex>=audioList.size){
currentIndex--
checkPrevAndNext(currentIndex)
return
}
checkPrevAndNext(currentIndex)
audioView?.get()?.setContent("第${currentIndex+1}首")
prepareAsync{ result,_->
if (result){
audioView?.get()?.setPlayEnable(true)
if (isAutoPlay) start(0,false)
}
}
}
override fun previous() {
if (audioPlayer?.isPlaying==true){
audioPlayer?.stop()
}
audioPlayer?.reset()
currentIndex--
if (currentIndex<0){
currentIndex=0
checkPrevAndNext(currentIndex)
return
}
checkPrevAndNext(currentIndex)
audioView?.get()?.setContent("第${currentIndex+1}首")
if (currentIndex == 0){
audioView?.get()?.setPrevEnable(false)
}
prepareAsync{ result,_->
if (result){
audioView?.get()?.setPlayEnable(true)
if (isAutoPlay) start(0,false)
}
}
}
private fun checkPrevAndNext(index: Int){
if (index == 0){
audioView?.get()?.setPrevEnable(false)
}
if (index>=audioList.size){
audioView?.get()?.setNextEnable(false)
}
if (index>0 && index<audioList.size-1){
audioView?.get()?.setPrevEnable(true)
audioView?.get()?.setNextEnable(true)
}
}
override fun release() {
audioView?.clear()
audioView=null
onPrepare=null
onError=null
bufferUpdate=null
audioPlayer?.reset()
audioPlayer?.release()
audioPlayer = null
}
fun setOnPrepareListener(onPrepare: () -> Unit) {
this.onPrepare = onPrepare
}
fun setOnErrorListener(onError: () -> Unit) {
this.onError = onError
}
fun setOnBufferListener(bufferUpdate: (Int) -> Unit) {
this.bufferUpdate = bufferUpdate
}
fun setOnCompleteListener(onComplete: () -> Unit) {
this.onComplete = onComplete
}
/**
* 在视频页面必须停止播放音频,释放资源。在这里需要记录当前的播放状态,播放进度
*/
fun pauseForVideo() {
}
/**
* 因视频暂停音频播放后的恢复操作
*/
fun restartAudio(){
}
class AudioPauseStatus{
var playStatus:Int = STATUS_STOP
var duration = 0
}
}
\ No newline at end of file
package com.yidian.shenghuoquan.newscontent.audio
import android.app.Service
import android.content.Intent
import android.graphics.PixelFormat
import android.os.Build
import android.os.IBinder
import android.util.Log
import android.view.*
import android.view.WindowManager.LayoutParams.*
import androidx.core.view.isGone
import com.yidian.shenghuoquan.newscontent.utils.audioManager
import com.yidian.shenghuoquan.newscontent.widget.FloatAudioView
/**
* 主要控制音频的生命周期
*/
class AudioService : Service() {
private val TAG = "AudioService"
private var windowManager:WindowManager?=null
private lateinit var rootView: FloatAudioView
override fun onCreate() {
super.onCreate()
windowManager = getSystemService(WINDOW_SERVICE) as WindowManager?
rootView = FloatAudioView(this)
rootView.setPlayEnable(false)
audioManager.prepareAsync { result,_->
Log.e(TAG, "onCreate: prepare$result" )
if (result){
rootView.setContent("第一首歌")
rootView.setPlayEnable(true)
}
}
audioManager.setOnErrorListener {
Log.e(TAG, "onError: =========" )
}
rootView.setOnCloseListener {
stopSelf()
}
}
override fun onBind(intent: Intent): IBinder? {
return null
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
showFloatingWindow()
return START_STICKY
}
private fun showFloatingWindow(){
val params = WindowManager.LayoutParams()
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
params.type = TYPE_APPLICATION_OVERLAY
}else{
params.type = TYPE_PHONE
}
params.packageName = packageName
params.flags = params.flags or FLAG_HARDWARE_ACCELERATED
params.flags = params.flags or FLAG_NOT_FOCUSABLE or FLAG_NOT_TOUCH_MODAL
params.flags = params.flags or FLAG_LAYOUT_INSET_DECOR or FLAG_LAYOUT_IN_SCREEN
params.width = MATCH_PARENT
params.height = WRAP_CONTENT
params.format = PixelFormat.TRANSPARENT
params.gravity = Gravity.BOTTOM
params.x = 0
params.y = 500
windowManager?.addView(rootView,params)
audioManager.bindAudioView(rootView)
}
override fun onDestroy() {
super.onDestroy()
rootView.isGone = true
windowManager?.removeView(rootView)
windowManager =null
audioManager.release()
}
}
\ No newline at end of file
package com.yidian.shenghuoquan.newscontent.audio
interface IAudioControl {
fun start(progress: Int = -1,user:Boolean=true)
fun next()
fun previous()
fun pause()
fun stop()
fun isPlaying():Boolean
fun release()
fun seekTo(progress: Int)
fun bindAudioView(view: IAudioView)
}
interface IAudioView{
fun setPrevEnable(enable:Boolean)
fun setNextEnable(enable:Boolean)
fun setPlayEnable(enable:Boolean)
fun setContent(content:String)
fun updatePlayUi(isPlay:Boolean)
fun bindAudioControl(control: IAudioControl)
}
\ No newline at end of file
package com.yidian.shenghuoquan.newscontent.service
import com.yidian.xarc.xrouter.ResultResolver
import com.yidian.yac.core.zap.ZapService
import org.json.JSONObject
class UserService : ZapService() {
companion object {
const val serviceName: String = "UserService"
}
private lateinit var resolver: ResultResolver
override fun onAction(name: String, action: String, params: Any, options: Any, resolver: ResultResolver) {
this.resolver = resolver
params as JSONObject
val path = params.optString("path")
val body = params.optJSONObject("body")
when (action) {
"addComment" -> addComment(path, body)
"like" -> like(path, body)
}
}
override fun onExit() {
}
override fun onInit() {
}
private fun addComment(path: String, params: JSONObject) {
}
private fun like(path: String, params: JSONObject) {
}
}
package com.yidian.shenghuoquan.newscontent.ui.alive;
import android.util.Base64;
import java.util.Random;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
/**
* Created by mafuxin on 2018/5/23.
*/
public class GenerateSign {
public static String appSign(String apiKey, String secret, long currtTime, long expireTime) {
try {
int rdm = Math.abs(new Random().nextInt());
String plainText = String.format("a=%s&b=%d&c=%d&d=%d", apiKey, expireTime, currtTime,rdm);
byte[] hmacDigest = HmacSha1(plainText, secret);
byte[] signContent = new byte[hmacDigest.length + plainText.getBytes().length];
System.arraycopy(hmacDigest, 0, signContent, 0, hmacDigest.length);
System.arraycopy(plainText.getBytes(), 0, signContent, hmacDigest.length,
plainText.getBytes().length);
return Base64Encode(signContent).replaceAll("[\\s*\t\n\r]", "");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 生成base64编码
*
* @param binaryData
* @return
*/
public static String Base64Encode(byte[] binaryData) {
String encodedstr = Base64.encodeToString(binaryData, Base64.DEFAULT);
return encodedstr;
}
/**
* 生成hmacsha1签名
*
* @param binaryData
* @param key
* @return
* @throws Exception
*/
public static byte[] HmacSha1(byte[] binaryData, String key) throws Exception {
Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
mac.init(secretKey);
byte[] HmacSha1Digest = mac.doFinal(binaryData);
return HmacSha1Digest;
}
/**
* 生成hmacsha1签名
*
* @param plainText
* @param key
* @return
* @throws Exception
*/
public static byte[] HmacSha1(String plainText, String key) throws Exception {
return HmacSha1(plainText.getBytes(), key);
}
}
package com.yidian.shenghuoquan.newscontent.ui.dialog
import android.app.Activity
import android.app.Dialog
import android.os.Bundle
import android.view.Gravity
import android.view.KeyEvent
import android.view.View
import android.view.WindowManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.yidian.bcommon.widget.YdMaxRecyclerView
import com.yidian.nightmode.widget.YdImageView
import com.yidian.nightmode.widget.YdTextView
import com.yidian.shenghuoquan.newscontent.R
import com.yidian.shenghuoquan.newscontent.adapter.UpdateVersionDesAdapter
import com.yidian.shenghuoquan.newscontent.bean.IUpdateDialogCallback
import com.yidian.yac.pm.appupdate.AppUpdateEchoData
import com.yidian.yac.pm.appupdate.AppUpdateInfo
class UpdateVersionDialog(private val activity: Activity, themeResId: Int, private val updateDialogCallback :IUpdateDialogCallback): Dialog(activity, themeResId) {
private lateinit var ivUpdateClose: YdImageView
private lateinit var tvNewVersion: YdTextView
private lateinit var tvDown: YdTextView
private lateinit var rvDes: YdMaxRecyclerView
private lateinit var updateInfo: AppUpdateInfo<AppUpdateEchoData>
private val adapter = UpdateVersionDesAdapter()
init {
setDialog()
}
private fun setDialog(){
this.setCanceledOnTouchOutside(false)
this.setContentView(R.layout.update_version_dialog)
this.setOwnerActivity(activity)
ivUpdateClose = findViewById(R.id.iv_updateClose)
tvNewVersion = findViewById(R.id.tv_newVersion)
tvDown = findViewById(R.id.tv_down)
rvDes = findViewById(R.id.rv_des)
rvDes.layoutManager = LinearLayoutManager(activity)
rvDes.adapter = adapter
setClickListener()
}
fun setData(updateInfo: AppUpdateInfo<AppUpdateEchoData>){
this.updateInfo = updateInfo
val forceUpdate = updateInfo.echo_data?.force_update
if(forceUpdate == true){
ivUpdateClose.visibility = View.GONE
}else{
ivUpdateClose.visibility = View.VISIBLE
}
val resultInfo = updateInfo.result?.get(0)
val versionShow = resultInfo?.package_version
tvNewVersion.text = "发现新版本V$versionShow"
var note = resultInfo?.note
var desList: ArrayList<String>? = null
if(!note.isNullOrEmpty()){
if(note.endsWith(";") || note.endsWith(";")){
note = note.substring(0, note.length - 1)
}
when {
note.contains(";") -> {
desList = note.split(";") as ArrayList<String>
}
note.contains(";") -> {
desList = note.split(";") as ArrayList<String>
}
else -> {
desList = ArrayList()
desList.add(note)
}
}
}
if(desList != null){
adapter.update(desList)
}
}
private fun setClickListener(){
ivUpdateClose.setOnClickListener {
dismiss()
}
tvDown.setOnClickListener {
tvDown.isEnabled = false
tvDown.setBackgroundResource(R.drawable.bg_gray_radio)
tvDown.text = "下载中..."
updateDialogCallback.downloadCallback(updateInfo)
}
setOnKeyListener { _, keyCode, event -> keyCode == KeyEvent.KEYCODE_BACK && event?.repeatCount == 0 }
}
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
}
}
package com.yidian.shenghuoquan.newscontent.ui.idcard
import android.graphics.BitmapFactory
import android.os.Bundle
import com.yidian.bcommon.base.BaseActivity
import com.yidian.bcommon.utils.ToolsUtil
import com.yidian.shenghuoquan.newscontent.databinding.ActivityIdcardResultBinding
/**
* Author: sym
* Date: 2021/5/20 6:51 PM
* Describe:
*/
class IDCardResultActivity:BaseActivity<ActivityIdcardResultBinding>() {
override fun createViewBinding(): ActivityIdcardResultBinding {
return ActivityIdcardResultBinding.inflate(layoutInflater)
}
override fun getXPageName(): String {
return ""
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val intent = intent
val bundle = intent.extras
val portraitimg = bundle!!.getByteArray("portraitimg_bitmap")
val iDCardImg = bundle.getByteArray("idcardimg_bitmap")
if (portraitimg != null) {
val bmpPortraitImg = BitmapFactory.decodeByteArray(portraitimg, 0, portraitimg.size)
viewBind.resultFaceImage.setImageBitmap(bmpPortraitImg)
}
if (iDCardImg != null) {
val bmpIDCardImg = BitmapFactory.decodeByteArray(iDCardImg, 0, iDCardImg.size)
viewBind.resultIdcardImage.setImageBitmap(bmpIDCardImg)
ToolsUtil.saveImage(bmpIDCardImg, ToolsUtil.randomName() + ".jpg", this)
}
}
}
package com.yidian.shenghuoquan.newscontent.ui.popwindow
import android.app.Activity
import android.graphics.drawable.ColorDrawable
import android.view.*
import android.widget.PopupWindow
import androidx.recyclerview.widget.LinearLayoutManager
import com.yidian.bcommon.cardutils.adapter.OnItemClickListener
import com.yidian.bcommon.widget.YdMaxRecyclerView
import com.yidian.nightmode.widget.YdImageView
import com.yidian.shenghuoquan.newscontent.R
import com.yidian.shenghuoquan.newscontent.adapter.FeedbackDetailAdapter
import com.yidian.shenghuoquan.newscontent.bean.FeedbackBean
import com.yidian.utils.ToastUtil
class FeedbackDetailPopupWindow(private val activity: Activity, private val parent: View, private val feedbackBean: FeedbackBean, private val feedbackType: String) {
companion object{
const val SHIELD = "shield"
const val FEEDBACK = "feedback"
}
private val view: View = LayoutInflater.from(activity).inflate(R.layout.feedback_detail_popup_window, null)
private val rvContent = view.findViewById<YdMaxRecyclerView>(R.id.rv_content)
private val ivBack = view.findViewById<YdImageView>(R.id.iv_back)
private val mPopUpWindow = PopupWindow(view)
private val adapter: FeedbackDetailAdapter by lazy { FeedbackDetailAdapter() }
init {
mPopUpWindow.isFocusable = false
mPopUpWindow.isTouchable = true
mPopUpWindow.isOutsideTouchable = true
initView()
setClickListener()
}
private fun initView(){
rvContent.layoutManager = LinearLayoutManager(activity)
rvContent.adapter = adapter
when(feedbackType){
SHIELD -> adapter.update(feedbackBean.tag)
FEEDBACK -> adapter.update(feedbackBean.reason)
}
}
private fun setClickListener(){
mPopUpWindow.setOnDismissListener {
val lp: WindowManager.LayoutParams = activity.window.attributes
lp.alpha = 1.0f
activity.window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
activity.window.attributes = lp
}
ivBack.setOnClickListener {
dismiss()
val feedbackPopupWindow = FeedbackPopupWindow(activity, parent, feedbackBean)
feedbackPopupWindow.show()
}
adapter.setOnItemClickListener(object : OnItemClickListener<String> {
override fun onClick(view: View?, position: Int, item: String?) {
item?.let {
ToastUtil.showToast(activity, "将为您减少此类内容推荐")
dismiss()
}
}
})
}
fun show(){
if (activity.isFinishing) {
return
}
mPopUpWindow.width = ViewGroup.LayoutParams.MATCH_PARENT
mPopUpWindow.height = ViewGroup.LayoutParams.WRAP_CONTENT
mPopUpWindow.setBackgroundDrawable(ColorDrawable(0x00000000))
mPopUpWindow.isOutsideTouchable = true
mPopUpWindow.isFocusable = true
mPopUpWindow.animationStyle = R.style.PopupWindow_anim_style
mPopUpWindow.showAtLocation(parent, Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, 0)
val lp: WindowManager.LayoutParams = activity.window.attributes
lp.alpha = 0.6f
activity.window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
activity.window.attributes = lp
}
fun dismiss() {
if (mPopUpWindow.isShowing) {
mPopUpWindow.dismiss()
}
}
}
package com.yidian.shenghuoquan.newscontent.ui.popwindow
import android.app.Activity
import android.graphics.drawable.ColorDrawable
import android.view.*
import android.widget.PopupWindow
import com.yidian.bcommon.utils.YdToastUtil
import com.yidian.nightmode.widget.YdLinearLayout
import com.yidian.shenghuoquan.newscontent.R
import com.yidian.shenghuoquan.newscontent.bean.FeedbackBean
class FeedbackPopupWindow(private val activity: Activity, private val parent: View, private val feedbackBean: FeedbackBean) {
private val view: View = LayoutInflater.from(activity).inflate(R.layout.feedback_popup_window, null)
private val llyUninterested = view.findViewById<YdLinearLayout>(R.id.lly_uninterested)
private val llyShield = view.findViewById<YdLinearLayout>(R.id.lly_shield)
private val llyInferior = view.findViewById<YdLinearLayout>(R.id.lly_inferior)
private val llyBlock = view.findViewById<YdLinearLayout>(R.id.lly_block)
private val mPopUpWindow = PopupWindow(view)
init {
mPopUpWindow.isFocusable = false
mPopUpWindow.isTouchable = true
mPopUpWindow.isOutsideTouchable = true
setClickListener()
}
private fun setClickListener(){
mPopUpWindow.setOnDismissListener {
val lp: WindowManager.LayoutParams = activity.window.attributes
lp.alpha = 1.0f
activity.window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
activity.window.attributes = lp
}
llyUninterested.setOnClickListener {
val imgUrl = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic.90sjimg.com%2Fdesign%2F01%2F40%2F17%2F07%2F58f7227f997dc.png&refer=http%3A%2F%2Fpic.90sjimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614927945&t=8957cd0434852595d03de955b704416e"
YdToastUtil.showToast(activity, "将为您减少此类内容推荐", imgUrl)
dismiss()
}
llyShield.setOnClickListener {
dismiss()
val feedbackDetailPopupWindow = FeedbackDetailPopupWindow(activity, parent, feedbackBean, FeedbackDetailPopupWindow.SHIELD)
feedbackDetailPopupWindow.show()
}
llyInferior.setOnClickListener {
dismiss()
val feedbackDetailPopupWindow = FeedbackDetailPopupWindow(activity, parent, feedbackBean, FeedbackDetailPopupWindow.FEEDBACK)
feedbackDetailPopupWindow.show()
}
llyBlock.setOnClickListener {
YdToastUtil.showToast(activity, "将为您减少此类内容推荐")
dismiss()
}
}
fun show(){
if (activity.isFinishing) {
return
}
mPopUpWindow.width = ViewGroup.LayoutParams.MATCH_PARENT
mPopUpWindow.height = ViewGroup.LayoutParams.WRAP_CONTENT
mPopUpWindow.setBackgroundDrawable(ColorDrawable(0x00000000))
mPopUpWindow.isOutsideTouchable = true
mPopUpWindow.isFocusable = true
mPopUpWindow.animationStyle = R.style.PopupWindow_anim_style
mPopUpWindow.showAtLocation(parent, Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, 0)
val lp: WindowManager.LayoutParams = activity.window.attributes
lp.alpha = 0.6f
activity.window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
activity.window.attributes = lp
}
fun dismiss() {
if (mPopUpWindow.isShowing) {
mPopUpWindow.dismiss()
}
}
}
package com.yidian.shenghuoquan.newscontent.viewholder package com.yidian.shenghuoquan.newscontent.ui.store.viewholder
import android.view.View import android.view.View
import android.widget.TextView import android.widget.TextView
......
package com.yidian.shenghuoquan.newscontent.utils;
import android.app.Activity;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.view.Gravity;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.WindowManager.LayoutParams;
import android.widget.PopupWindow;
public class HeightProvider extends PopupWindow implements OnGlobalLayoutListener {
private final Activity mActivity;
private final View rootView;
private HeightListener listener;
private static int heightMax; // 记录popup内容区的最大高度
private static int keyboardHeight; // 记录keyboard高
public HeightProvider(Activity activity) {
super(activity);
this.mActivity = activity;
// 基础配置
rootView = new View(activity);
setContentView(rootView);
// 监听全局Layout变化
rootView.getViewTreeObserver().addOnGlobalLayoutListener(this);
setBackgroundDrawable(new ColorDrawable(0));
// 设置宽度为0,高度为全屏
setWidth(0);
setHeight(LayoutParams.MATCH_PARENT);
// 设置键盘弹出方式
setSoftInputMode(LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
}
public HeightProvider init() {
if (!isShowing()) {
final View view = mActivity.getWindow().getDecorView();
// 延迟加载popupwindow,如果不加延迟就会报错
view.post(() -> showAtLocation(view, Gravity.NO_GRAVITY, 0, 0));
}
return this;
}
public HeightProvider setHeightListener(HeightListener listener) {
this.listener = listener;
return this;
}
@Override
public void onGlobalLayout() {
Rect rect = new Rect();
rootView.getWindowVisibleDisplayFrame(rect);
if (rect.bottom > heightMax) {
heightMax = rect.bottom;
}
// 两者的差值就是键盘的高度
keyboardHeight = heightMax - rect.bottom;
if (listener != null) {
listener.onHeightChanged(heightMax, keyboardHeight);
}
}
public interface HeightListener {
void onHeightChanged(int heightMax, int height);
}
public static boolean isKeyboardShowing() {
return keyboardHeight > heightMax / 3;
}
public static int getHeightMax() {
return heightMax;
}
}
package com.yidian.shenghuoquan.newscontent.utils;
import android.os.Build;
import android.text.TextUtils;
import androidx.annotation.StringDef;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author sun on 2018/7/5.
*/
public class RomUtils {
private static final String TAG = "RomUtils";
static final String ROM_MIUI = "MIUI";
static final String ROM_EMUI = "EMUI";
static final String ROM_VIVO = "VIVO";
static final String ROM_OPPO = "OPPO";
static final String ROM_FLYME = "FLYME";
static final String ROM_SMARTISAN = "SMARTISAN";
static final String ROM_QIKU = "QIKU";
static final String ROM_LETV = "LETV";
static final String ROM_LENOVO = "LENOVO";
static final String ROM_NUBIA = "NUBIA";
static final String ROM_ZTE = "ZTE";
static final String ROM_COOLPAD = "COOLPAD";
static final String ROM_UNKNOWN = "UNKNOWN";
@StringDef({
ROM_MIUI, ROM_EMUI, ROM_VIVO, ROM_OPPO, ROM_FLYME,
ROM_SMARTISAN, ROM_QIKU, ROM_LETV, ROM_LENOVO, ROM_ZTE,
ROM_COOLPAD, ROM_UNKNOWN
})
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
public @interface RomName {
}
private static final String SYSTEM_VERSION_MIUI = "ro.miui.ui.version.name";
private static final String SYSTEM_VERSION_EMUI = "ro.build.version.emui";
private static final String SYSTEM_VERSION_VIVO = "ro.vivo.os.version";
private static final String SYSTEM_VERSION_OPPO = "ro.build.version.opporom";
private static final String SYSTEM_VERSION_FLYME = "ro.build.display.id";
private static final String SYSTEM_VERSION_SMARTISAN = "ro.smartisan.version";
private static final String SYSTEM_VERSION_LETV = "ro.letv.eui";
private static final String SYSTEM_VERSION_LENOVO = "ro.lenovo.lvp.version";
private static String getSystemProperty(String propName) {
return SystemProperties.get(propName, null);
}
@RomName
public static String getRomName() {
if (isMiuiRom()) {
return ROM_MIUI;
}
if (isHuaweiRom()) {
return ROM_EMUI;
}
if (isVivoRom()) {
return ROM_VIVO;
}
if (isOppoRom()) {
return ROM_OPPO;
}
if (isMeizuRom()) {
return ROM_FLYME;
}
if (isSmartisanRom()) {
return ROM_SMARTISAN;
}
if (is360Rom()) {
return ROM_QIKU;
}
if (isLetvRom()) {
return ROM_LETV;
}
if (isLenovoRom()) {
return ROM_LENOVO;
}
if (isZTERom()) {
return ROM_ZTE;
}
if (isCoolPadRom()) {
return ROM_COOLPAD;
}
return ROM_UNKNOWN;
}
public static String getDeviceManufacture() {
if (isMiuiRom()) {
return "小米";
}
if (isHuaweiRom()) {
return "华为";
}
if (isVivoRom()) {
return ROM_VIVO;
}
if (isOppoRom()) {
return ROM_OPPO;
}
if (isMeizuRom()) {
return "魅族";
}
if (isSmartisanRom()) {
return "锤子";
}
if (is360Rom()) {
return "奇酷";
}
if (isLetvRom()) {
return "乐视";
}
if (isLenovoRom()) {
return "联想";
}
if (isZTERom()) {
return "中兴";
}
if (isCoolPadRom()) {
return "酷派";
}
return Build.MANUFACTURER;
}
public static boolean isMiuiRom() {
return !TextUtils.isEmpty(getSystemProperty(SYSTEM_VERSION_MIUI));
}
public static boolean isHuaweiRom() {
return !TextUtils.isEmpty(getSystemProperty(SYSTEM_VERSION_EMUI));
}
public static boolean isVivoRom() {
return !TextUtils.isEmpty(getSystemProperty(SYSTEM_VERSION_VIVO));
}
public static boolean isOppoRom() {
return !TextUtils.isEmpty(getSystemProperty(SYSTEM_VERSION_OPPO));
}
public static boolean isMeizuRom() {
String meizuFlymeOSFlag = getSystemProperty(SYSTEM_VERSION_FLYME);
return !TextUtils.isEmpty(meizuFlymeOSFlag) && meizuFlymeOSFlag.toUpperCase().contains(ROM_FLYME);
}
public static boolean isSmartisanRom() {
return !TextUtils.isEmpty(getSystemProperty(SYSTEM_VERSION_SMARTISAN));
}
public static boolean is360Rom() {
String manufacturer = Build.MANUFACTURER;
return !TextUtils.isEmpty(manufacturer) && manufacturer.toUpperCase().contains(ROM_QIKU);
}
public static boolean isLetvRom() {
return !TextUtils.isEmpty(getSystemProperty(SYSTEM_VERSION_LETV));
}
public static boolean isLenovoRom() {
return !TextUtils.isEmpty(getSystemProperty(SYSTEM_VERSION_LENOVO));
}
public static boolean isCoolPadRom() {
String model = Build.MODEL;
String fingerPrint = Build.FINGERPRINT;
return (!TextUtils.isEmpty(model) && model.toLowerCase().contains(ROM_COOLPAD))
|| (!TextUtils.isEmpty(fingerPrint) && fingerPrint.toLowerCase().contains(ROM_COOLPAD));
}
public static boolean isZTERom() {
String manufacturer = Build.MANUFACTURER;
String fingerPrint = Build.FINGERPRINT;
boolean b = fingerPrint.toLowerCase().contains(ROM_NUBIA)
|| fingerPrint.toLowerCase().contains(ROM_ZTE);
return (!TextUtils.isEmpty(manufacturer) && b)
|| (!TextUtils.isEmpty(fingerPrint) && b);
}
public static boolean isDomesticSpecialRom() {
return RomUtils.isMiuiRom()
|| RomUtils.isHuaweiRom()
|| RomUtils.isMeizuRom()
|| RomUtils.is360Rom()
|| RomUtils.isOppoRom()
|| RomUtils.isVivoRom()
|| RomUtils.isLetvRom()
|| RomUtils.isZTERom()
|| RomUtils.isLenovoRom()
|| RomUtils.isCoolPadRom();
}
public static boolean isSmartisanR1() {
return Build.MODEL.contains("DE106");
}
/**
* Vivo沙雕刘海屏判断
*
* @return
*/
public static boolean isVivoStupidNotch() {
return isVivoX21() || isVivoX21S() || isVivoX23() || isVivoZ1() || isVivoZ3() ||
isVivoY81s() || isVivoY83() || isVivoY85() || isVivoY93() || isVivoY97();
}
public static boolean isVivoX21() {
return Build.MODEL.contains("vivo X21");
}
public static boolean isVivoX21S() {
return Build.MODEL.contains("V1814");
}
public static boolean isVivoX23() {
//X23普通 幻彩版
return Build.MODEL.contains("V1809") || Build.MODEL.contains("V1816");
}
public static boolean isVivoZ1() {
return Build.MODEL.contains("V1730");
}
public static boolean isVivoZ3() {
return Build.MODEL.contains("V1813BA");
}
public static boolean isVivoY81s() {
return Build.MODEL.contains("V1732");
}
public static boolean isVivoY83() {
return Build.MODEL.contains("Y83");
}
public static boolean isVivoY85() {
return Build.MODEL.contains("vivo Y85");
}
public static boolean isVivoY93() {
return Build.MODEL.contains("V1818");
}
public static boolean isVivoY97() {
return Build.MODEL.contains("V1813A") || Build.MODEL.contains("V1813T");
}
public static boolean isHonorV10() {
return Build.MODEL.contains("BKL-AL00");
}
public static boolean isHonor10() {
return Build.MODEL.contains("COL-AL10");
}
public static boolean isMiPad4() {
return TextUtils.equals(Build.MODEL, "MI PAD 4");
}
}
package com.yidian.shenghuoquan.newscontent.utils;
import android.text.TextUtils;
import java.lang.reflect.Method;
/**
* @author sun on 2018/7/5.
*/
public class SystemProperties {
private static final Method getStringProperty = getMethod(getClass("android.os.SystemProperties"));
private static Class<?> getClass(String name) {
try {
Class<?> cls = Class.forName(name);
if (cls == null) {
throw new ClassNotFoundException();
}
return cls;
} catch (ClassNotFoundException e) {
try {
return ClassLoader.getSystemClassLoader().loadClass(name);
} catch (ClassNotFoundException e1) {
return null;
}
}
}
private static Method getMethod(Class<?> clz) {
if (clz == null) return null;
try {
return clz.getMethod("get", String.class);
} catch (Exception e) {
return null;
}
}
public static String get(String key) {
if (getStringProperty != null) {
try {
Object value = getStringProperty.invoke(null, key);
if (value == null) {
return "";
}
return trimToEmpty(value.toString());
} catch (Exception ignored) {
}
}
return "";
}
public static String get(String key, String def) {
if (getStringProperty != null) {
try {
String value = (String) getStringProperty.invoke(null, key);
return defaultString(trimToNull(value), def);
} catch (Exception ignored) {
}
}
return def;
}
private static String defaultString(String str, String defaultStr) {
return str == null ? defaultStr : str;
}
private static String trimToNull(String str) {
String ts = trim(str);
return TextUtils.isEmpty(ts) ? null : ts;
}
private static String trimToEmpty(String str) {
return str == null ? "" : str.trim();
}
private static String trim(String str) {
return str == null ? null : str.trim();
}
}
package com.yidian.shenghuoquan.newscontent.utils
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody.Companion.asRequestBody
import java.io.File
class UploadFileUtils {
companion object{
fun fileToMultipartBodyPart(fileKey: String, file: File): MultipartBody.Part{
val requestFile = file.asRequestBody("multipart/form-data".toMediaTypeOrNull())
return MultipartBody.Part.createFormData(fileKey, file.name, requestFile)
}
}
}
\ No newline at end of file
package com.yidian.shenghuoquan.newscontent.utils
import com.yidian.shenghuoquan.newscontent.audio.AudioPlayerManager
val audioManager: AudioPlayerManager by lazy { AudioPlayerManager.instance }
\ No newline at end of file
package com.yidian.shenghuoquan.newscontent.widget;
import android.annotation.SuppressLint;
import android.content.Context;
import android.text.Layout;
import android.text.NoCopySpan;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.NonNull;
import com.yidian.nightmode.widget.YdTextView;
import com.yidian.shenghuoquan.newscontent.R;
public class ExpandTextView extends YdTextView {
private static final String TAG = "ExpandTextView";
private String originText = ""; //原始内容文本
private int initWidth = 0; //TextView可展示宽度
private int mMaxLines = 2; //TextView最大显示行数
private SpannableString SPAN_CLOSE = null; //收起的文本(颜色处理和点击监听)
private SpannableString SPAN_EXPAND = null; //展开的文本(颜色处理和点击监听)
private String TEXT_EXPAND = " 展开";
private String TEXT_CLOSE = " 收起";
private int SPAN_COLOR = R.color.video_transparent_50;
private boolean isClose = true;
private boolean isWidthModify = true; //用于控件宽高改变时通知重绘的判断,避免循环绘制
private ExpandClickListener l;
public ExpandTextView(Context context) {
super(context);
}
public ExpandTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ExpandTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
initWidth = getMeasuredWidth();
if(isWidthModify) {
notifyRefreshView();
isWidthModify = false;
}
}
/**
* 初始化"展开"的Span文本,即收起状态的文本尾
*/
private void initCloseEnd(){
String content = TEXT_EXPAND;
SPAN_CLOSE = new SpannableString(content);
SPAN_CLOSE.setSpan(new NoRefCopySpan() {
@SuppressLint("ResourceType")
@Override
public void updateDrawState(TextPaint ds) {
ds.setColor(getResources().getColor(SPAN_COLOR));
ds.setUnderlineText(false);
}
@Override
public void onClick(@NonNull View widget) {
if (l!=null){
l.onClick(true);
}
ExpandTextView.super.setMaxLines(Integer.MAX_VALUE);
setExpandText(originText);
}
}, 0, content.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
/**
* 初始化"收起"的Span文本,即展开状态的文本尾
*/
private void initExpandEnd(){
String content = TEXT_CLOSE;
SPAN_EXPAND = new SpannableString(content);
SPAN_EXPAND.setSpan(new NoRefCopySpan() {
@SuppressLint("ResourceType")
@Override
public void updateDrawState(TextPaint ds) {
ds.setColor(getResources().getColor(SPAN_COLOR));
ds.setUnderlineText(false);
}
@Override
public void onClick(@NonNull View widget) {
if (l!=null){
l.onClick(false);
}
ExpandTextView.super.setMaxLines(mMaxLines);
setCloseText(originText);
}
}, 0, content.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
/**
* 设置收起状态时的文本
*/
private void setCloseText(CharSequence text) {
if(SPAN_CLOSE == null){
initCloseEnd();
}
boolean appendShowAll = false;//true不需要展开收起功能(文件行数小于或等于最大行),false需要展开收起功能
originText = text.toString();
int maxLines = getMaxLines();
String workingText = originText;
if (maxLines != -1) {
Layout layout = createWorkingLayout(workingText);
if (layout.getLineCount() > maxLines) {
//获取一行显示字符个数,然后截取字符串数
workingText = originText.substring(0, layout.getLineEnd(maxLines - 1)).trim();// 收起状态原始文本截取展示的部分
String showText = originText.substring(0, layout.getLineEnd(maxLines - 1)).trim() + "..." + SPAN_CLOSE;
Layout layout2 = createWorkingLayout(showText);
//对workingText进行-1截取,直到展示行数==最大行数,并且添加SPAN_CLOSE后刚好占满最后一行
while (layout2.getLineCount() > maxLines) {
int lastSpace = workingText.length()-1;
if (lastSpace == -1) {
break;
}
workingText = workingText.substring(0, lastSpace);
layout2 = createWorkingLayout(workingText + "..." + SPAN_CLOSE);
}
appendShowAll = true;
workingText = workingText + "...";
}
}
setText(workingText);
if (appendShowAll) {
// 必须使用append,不能在上面使用+连接,否则spannable会无效
append(SPAN_CLOSE);
setMovementMethod(LinkMovementMethod.getInstance());
}
invalidate();
post(this::requestLayout);
}
/**
* 设置展开状态时的文本
*/
@SuppressLint("SetTextI18n")
private void setExpandText(String text) {
if(SPAN_EXPAND == null){
initExpandEnd();
}
Layout layout1 = createWorkingLayout(text);
Layout layout2 = createWorkingLayout(text + TEXT_CLOSE);
// 展示全部原始内容时 如果 TEXT_CLOSE 需要换行才能显示完整,则直接将TEXT_CLOSE展示在下一行
if(layout2.getLineCount() > layout1.getLineCount()){
setText(originText + "\n");
}else{
setText(originText);
}
append(SPAN_EXPAND);
setMovementMethod(LinkMovementMethod.getInstance());
invalidate();
post(this::requestLayout);
}
/**
* 返回textview的显示区域的layout,该textview的layout并不会显示出来
* 只是用其宽度来比较要显示的文字是否过长。
*/
private Layout createWorkingLayout(String workingText) {
return new StaticLayout(workingText, getPaint(), initWidth - getPaddingLeft() - getPaddingRight(),
Layout.Alignment.ALIGN_NORMAL, getLineSpacingMultiplier(), getLineSpacingExtra(), false);
}
/**
* sdk>=16,可以通过xml进行配置,但16以下必须用该方法配置
*/
@Override
public void setMaxLines(int maxLines) {
this.mMaxLines = maxLines;
super.setMaxLines(maxLines);
}
/**
* @param originText 待显示的原文本;
* @param isClose 设置TextView的初始状态是否为收起;
* 设置文本时,需要调用该方法来代替setText。若直接使用setText方法设置文本,
* 该控件只会作为普通TextView显示。
*/
public void setText(String originText, boolean isClose) {
this.originText = originText;
this.isClose = isClose;
isWidthModify = true;
notifyRefreshView();
}
/**
* 修改设置后通知重绘,setText(String originText, Boolean isClose)方法不需要调用
*/
public void notifyRefreshView() {
if(isClose) {
ExpandTextView.super.setMaxLines(mMaxLines);
setCloseText(originText);
} else {
ExpandTextView.super.setMaxLines(Integer.MAX_VALUE);
setExpandText(originText);
}
}
/**
* @param colorId 展开和收起时,文本尾的Span文本的颜色;
* 设置展开和收起时文本尾的Span文本的颜色(若不以该方法设置,则默认为R.color.red)。
*/
public void setLabelTextColor(int colorId) {
SPAN_COLOR = colorId;
initExpandEnd();
initCloseEnd();
}
/**
* @param str 收起时,文本尾代表"展开"的Span文本内容;
* 设置文本尾的"展开"Span文本的内容(若不以该方法设置,则默认为"展开")。
*/
public void setExpandLabelText(String str) {
TEXT_EXPAND = str;
initExpandEnd();
}
/**
* @param str 展开时,文本尾代表"收起"的Span文本内容;
* 设置文本尾的"收起"Span文本的内容(若不以该方法设置,则默认为"收起")。
*/
public void setCLOSELabelText(String str) {
TEXT_CLOSE = str;
initCloseEnd();
}
/**
* 实现NoCopySpan的原因是,为了防止Span在onSaveInstanceState时被复制保存,导致内存泄漏
*/
public static class NoRefCopySpan extends ClickableSpan implements NoCopySpan {
@Override
public void onClick(@NonNull View widget) {
//等待子类继承
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
}
}
public void setOnExpandClickListener(ExpandClickListener listener){
this.l = listener;
}
interface ExpandClickListener{
void onClick(boolean isExpand);
}
}
\ No newline at end of file
package com.yidian.shenghuoquan.newscontent.widget
import android.content.Context
import android.util.AttributeSet
import com.yidian.nightmode.widget.YdTextView
class ExpandTextViewReal @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0
) :YdTextView(context, attrs, defStyle) {
}
\ No newline at end of file
package com.yidian.shenghuoquan.newscontent.widget
import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import com.yidian.shenghuoquan.newscontent.R
import com.yidian.shenghuoquan.newscontent.audio.IAudioControl
import com.yidian.shenghuoquan.newscontent.audio.IAudioView
import java.lang.ref.WeakReference
class FloatAudioView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
FrameLayout(context, attrs) , IAudioView {
private var close: (() -> Unit)?=null
private val TAG = "FloatAudioView"
private lateinit var ivPower:ImageView
private lateinit var ivPrev:ImageView
private lateinit var ivNext:ImageView
private lateinit var ivPlay:ImageView
private lateinit var tvContent:TextView
private var audioControl:WeakReference<IAudioControl>?=null
init {
inflate(context, R.layout.float_audio_layout,this)
initView()
initListener()
}
private fun initListener() {
ivPower.setOnClickListener {
Log.e(TAG, "initListener: ivPower ==" )
visibility = View.GONE
audioControl?.get()?.release()
close?.invoke()
}
ivPrev.setOnClickListener {
Log.e(TAG, "initListener: iv ivPrev" )
audioControl?.get()?.previous()
}
ivNext.setOnClickListener {
Log.e(TAG, "initListener: iv next" )
audioControl?.get()?.next()
}
ivPlay.setOnClickListener {
Log.e(TAG, "initListener: iv play" )
if (audioControl?.get()?.isPlaying() ==true){
audioControl?.get()?.pause()
updatePlayUi(false)
}else{
audioControl?.get()?.start()
updatePlayUi(true)
}
}
}
private fun initView() {
ivPower = findViewById(R.id.iv_power)
ivPlay = findViewById(R.id.iv_audio_play)
ivPrev = findViewById(R.id.iv_prev)
ivNext = findViewById(R.id.iv_next)
tvContent = findViewById(R.id.tv_content)
}
override fun bindAudioControl(control: IAudioControl) {
audioControl = WeakReference(control)
}
override fun setPrevEnable(enable: Boolean) {
ivPrev.isEnabled = enable
if (enable){
ivPrev.setImageResource(R.drawable.skip_previous)
}else{
ivPrev.setImageResource(R.drawable.skip_previous_gray)
}
}
override fun setPlayEnable(enable: Boolean) {
ivPlay.isEnabled = enable
}
override fun setNextEnable(enable:Boolean){
ivNext.isEnabled = enable
if (enable){
ivNext.setImageResource(R.drawable.skip_next)
}else{
ivNext.setImageResource(R.drawable.skip_next_gray)
}
}
override fun setContent(content: String) {
if (::tvContent.isInitialized){
tvContent.text = content
}
}
override fun updatePlayUi(isPlay: Boolean) {
ivPlay.setImageResource(if (isPlay)R.drawable.audio_start else R.drawable.audio_pause)
}
fun setOnCloseListener(close:()->Unit){
this.close = close
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
audioControl?.clear()
audioControl=null
}
}
\ No newline at end of file
...@@ -3,47 +3,6 @@ ...@@ -3,47 +3,6 @@
package="com.yidian.shenghuoquan.newscontent"> package="com.yidian.shenghuoquan.newscontent">
<application> <application>
<activity
android:name="com.yidian.shenghuoquan.broot.ui.FlashActivity"
android:theme="@style/FlashTheme">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.MainActivity"
android:launchMode="singleTask" />
<activity android:name=".ui.DeepLinkActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="link_news"
android:scheme="ydsubway" />
</intent-filter>
</activity>
<activity
android:name=".ui.NewsContentActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize|uiMode" />
<service
android:name=".audio.AudioService"
android:enabled="true"
android:exported="true" />
<activity
android:name=".ui.alive.AliveTestActivity"
android:theme="@style/Transparent" />
<activity
android:name=".ui.idcard.IDCardTestActivity"
android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.auth.LifeAccountEnterpriseAuthCompleteActivity" android:name=".ui.auth.LifeAccountEnterpriseAuthCompleteActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
...@@ -53,60 +12,38 @@ ...@@ -53,60 +12,38 @@
<activity <activity
android:name=".ui.auth.LifeAccountCreateCompleteActivity" android:name=".ui.auth.LifeAccountCreateCompleteActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity
android:name=".ui.idcard.IDCardResultActivity"
android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.ProtocolActivity" android:name=".ui.ProtocolActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity
android:name=".ui.ProductSupportActivity"
android:theme="@style/Transparent" />
<activity android:name=".ui.LoginLifeCircleActivity" /> <activity android:name=".ui.LoginLifeCircleActivity" />
<activity <activity
android:name=".ui.store.StoreManagementActivity" android:name=".ui.store.StoreManagementActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.store.EditStoreActivity" android:name=".ui.store.EditStoreActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.store.SelectAddressActivity" android:name=".ui.store.SelectAddressActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.store.SearchAddActivity" android:name=".ui.store.SearchAddActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.auth.LifeAccountIdentityActivity" android:name=".ui.auth.LifeAccountIdentityActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.auth.LifeAccountAuthActivity" android:name=".ui.auth.LifeAccountAuthActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity
android:name=".ui.LifeAccountEnterpriseCertificationActivity"
android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.auth.LifeAccountCreateActivity" android:name=".ui.auth.LifeAccountCreateActivity"
android:theme="@style/Transparent" android:theme="@style/Transparent"
android:windowSoftInputMode="stateHidden|adjustResize" /> android:windowSoftInputMode="stateHidden|adjustResize" />
<activity <activity
android:name=".ui.auth.LifeAccountPersonalAuthActivity" android:name=".ui.auth.LifeAccountPersonalAuthActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.auth.LifeAccountEnterpriseAuthActivity" android:name=".ui.auth.LifeAccountEnterpriseAuthActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity <activity
android:name=".personnel.ui.MyStaffActivity" android:name=".personnel.ui.MyStaffActivity"
android:launchMode="singleTask" android:launchMode="singleTask"
...@@ -129,20 +66,16 @@ ...@@ -129,20 +66,16 @@
<activity <activity
android:name=".ui.setting.SystemSettingActivity" android:name=".ui.setting.SystemSettingActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.center.MerchantCenterActivity" android:name=".ui.center.MerchantCenterActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.center.MerchantInfoActivity" android:name=".ui.center.MerchantInfoActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
<activity <activity
android:name=".ui.center.LifeAccountModifyNameActivity" android:name=".ui.center.LifeAccountModifyNameActivity"
android:theme="@style/Transparent" android:theme="@style/Transparent"
android:windowSoftInputMode="stateVisible" /> android:windowSoftInputMode="stateVisible" />
<activity <activity
android:name=".ui.center.MerchantAuthInfoActivity" android:name=".ui.center.MerchantAuthInfoActivity"
android:theme="@style/Transparent" /> android:theme="@style/Transparent" />
......
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:background="@color/black"
tools:viewBindingIgnore="true">
<com.yidian.shenghuoquan.newscontent.widget.CustomCoverVideo
android:id="@+id/ccv_detail"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<FrameLayout
android:id="@+id/video_float_ll"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.yidian.nightmode.widget.YdLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:orientation="vertical">
<com.yidian.nightmode.widget.YdLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="76dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/iv_author"
android:layout_width="30dp"
android:layout_height="30dp"
android:padding="2dp"
android:background="@drawable/circle_white_bg"
android:layout_marginStart="20dp"
android:scaleType="centerCrop" />
<com.yidian.nightmode.widget.YdTextView
android:id="@+id/tv_author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
tools:text="天王盖地虎"
android:textColor="@color/white"
android:textSize="14sp" />
<com.yidian.shenghuoquan.newscontent.widget.chameleon.SubscribeButton
android:id="@+id/sb_subscription"
android:layout_width="36dp"
android:layout_height="16dp"
android:layout_marginStart="6dp"
android:gravity="center"
android:background="@drawable/yellow_radius_bg"
android:paddingStart="3dp"
android:paddingEnd="3dp"
android:text="@string/subscription"
android:textColor="@color/video_subscription"
android:textSize="9sp"
tools:ignore="SmallSp" />
</com.yidian.nightmode.widget.YdLinearLayout>
<com.yidian.shenghuoquan.newscontent.widget.ExpandTextView
android:id="@+id/tv_detail_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="76dp"
android:maxLines="2"
android:layout_marginBottom="10dp"
android:textColor="@color/white"
android:textSize="15sp" />
<com.yidian.nightmode.widget.YdLinearLayout
android:id="@+id/video_comment_layout"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/black"
android:layout_marginTop="20dp"
android:gravity="center_vertical">
<com.yidian.nightmode.widget.YdTextView
android:id="@+id/tv_comment_bottom"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:paddingBottom="5dp"
android:layout_marginStart="20dp"
android:layout_weight="1"
android:text="写评论"
android:textColor="@color/gray_888888"
android:textSize="14sp" />
<com.yidian.nightmode.widget.YdImageView
android:visibility="gone"
android:id="@+id/iv_comment_bottom"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="20dp"
android:scaleType="centerCrop"
android:src="@mipmap/more_white" />
</com.yidian.nightmode.widget.YdLinearLayout>
</com.yidian.nightmode.widget.YdLinearLayout>
<LinearLayout
android:layout_width="44dp"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginEnd="12dp"
android:layout_marginBottom="84dp"
android:gravity="center_horizontal"
android:orientation="vertical">
<com.yidian.shenghuoquan.newscontent.widget.VideoThumbUpView
android:id="@+id/vt_thumb_up"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<com.yidian.nightmode.widget.YdImageView
android:id="@+id/iv_comment"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_marginTop="20dp"
android:scaleType="centerCrop"
android:src="@mipmap/video_comment" />
<com.yidian.nightmode.widget.YdTextView
android:id="@+id/tv_comment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="抢首评"
android:textColor="@color/white"
android:textSize="12sp" />
<com.yidian.nightmode.widget.YdImageView
android:id="@+id/iv_share"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_marginTop="20dp"
android:scaleType="centerCrop"
android:src="@mipmap/video_share" />
<com.yidian.nightmode.widget.YdTextView
android:id="@+id/tv_share"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="分享"
android:textColor="@color/white"
android:textSize="12sp" />
</LinearLayout>
</FrameLayout>
</FrameLayout>
\ 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