Commit 69bc9942 by 王佳洋

分离音频播放

parent a7efead0
......@@ -215,6 +215,7 @@ dependencies {
implementation project(":api:im")
implementation project(':m-dynamic')
implementation project(':m-course')
implementation project(":api:course")
implementation project(':m-article')
implementation project(':m-audioim')
implementation project(':m-fm')
......
......@@ -22,7 +22,6 @@ import com.ydl.media.view.PlayTypeEnum;
import com.ydl.media.view.PlayerFloatHelper;
import com.ydl.ydlcommon.utils.LogUtil;
import com.yidianling.common.tools.ToastUtil;
import com.yidianling.muse.event.MeditationFloatEvent;
import java.util.HashMap;
import java.util.Locale;
......@@ -191,7 +190,7 @@ public class PlayFragment extends Fragment implements View.OnClickListener,
tvTitle.setText(music.getTitle());
tvArtist.setText(music.getArtist());
sbProgress.setProgress((int) AudioPlayer.Companion.get().getAudioPosition());
sbProgress.setProgress((int) AudioPlayer.Companion.get().getCurrentPosition());
sbProgress.setSecondaryProgress(0);
// sbProgress.setMax((int) AudioPlayer.Companion.get().getDuration());
......
......@@ -3,28 +3,24 @@ package com.ydl.component.service.web;
import android.app.Activity;
import android.graphics.Rect;
import android.text.TextUtils;
import com.alibaba.android.arouter.launcher.ARouter;
import com.blankj.utilcode.util.ScreenUtils;
import com.ydl.confide.api.IConfideService;
import com.ydl.confide.home.event.ChangeAnotherExpertEvent;
import com.ydl.course.api.ICourseService;
import com.ydl.webview.H5JsBean;
import com.ydl.webview.H5Params;
import com.ydl.webview.NewH5Activity;
import com.ydl.ydl_router.manager.YDLRouterManager;
import com.ydl.ydl_router.manager.YDLRouterParams;
import com.ydl.ydlcommon.modular.ModularServiceManager;
import com.yidianling.common.tools.LogUtil;
import com.yidianling.common.tools.ToastUtil;
import com.yidianling.consultant.preview.GPreviewBuilder;
import com.yidianling.consultant.preview.UserViewInfo;
import com.yidianling.im.api.service.IImService;
import com.yidianling.muse.activity.ChooseMusicActivity;
//import static com.ydl.ydlcommon.router.IYDLRouterConstant.ROUTER_MUSE_PLAY;
import de.greenrobot.event.EventBus;
import com.yidianling.im.event.CloseBottomWebviewEvent;
import com.yidianling.muse.activity.ChooseMusicActivity;
import java.util.ArrayList;
import java.util.List;
......@@ -249,7 +245,15 @@ public class WVClickAbstractListener implements WebViewClientClickListener {
@Override
public void coursePlay(H5JsBean.H5JsCmd.Params params) {
if (TextUtils.isEmpty(params.getCourse_id())) {
ToastUtil.toastShort("参数错误,请重试");
return;
}
try {
ModularServiceManager.INSTANCE.provide(ICourseService.class).startCoursePlayActivity(mContext,
Integer.valueOf(params.getCourse_id()), params.getCoursePlayUrl(), 1, params.getMediaType());
} catch (Exception e) {
}
}
@Override
......
ext {
dev_mode = false//组件发布的时候需要设置为false
dev_mode = true//组件发布的时候需要设置为false
ydl2PublishVersion = "0.2.0.17"
ydlPublishVersion = [
// -------------- 业务模块 --------------
......
#Fri Jul 22 17:29:41 CST 2022
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.8.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
......@@ -38,6 +38,12 @@ tv.danmaku.ijk.media.player_arm64
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:theme="@style/CourseTheme" />
<activity
android:name=".coursePlay.AudioPlayActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:theme="@style/CourseTheme" />
<!--课程课后笔记列表-->
<activity
android:name=".coursePlay.CourseReplyListActivity"
......
......@@ -8,7 +8,6 @@ import android.graphics.Color
import android.os.Build
import android.os.Handler
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.OrientationHelper
import android.text.TextUtils
import android.view.View
import android.view.ViewGroup
......@@ -27,7 +26,6 @@ import com.ydl.media.audio.utils.PlayProgressUtil
import com.ydl.media.view.PlayTypeEnum
import com.ydl.media.view.PlayerFloatHelper
import com.ydl.ydl_image.module.GlideApp
import com.ydl.ydl_router.manager.YDLRouterManager
import com.ydl.ydlcommon.adapter.CommonRecyclerAdapter
import com.ydl.ydlcommon.base.BaseActivity
import com.ydl.ydlcommon.bean.ShareData
......@@ -247,32 +245,6 @@ class CoursePlayActivity : BaseActivity() {
)
updatePlayingListStatus(position)
// if (playList[index].mediaType == 2) {
// play_type = 1
// (playVideoView as CoursePlayItemViewVideo)?.play(position)
// }
// if (playList[index].mediaType == 1) {
// play_type = 0
// if (RxNetTool.isWifi(this@CoursePlayActivity)) {
// (playAudioView as CoursePlayItemViewAudio).playView!!.play(
// position
// )
// } else {
// if ((playAudioView as CoursePlayItemViewAudio).hasEnsureNetStatus) {
// (playAudioView as CoursePlayItemViewAudio).playView!!.play(
// position
// )
// } else {
// (playAudioView as CoursePlayItemViewAudio).setData(
// position,
// playList,
// courPlayBean!!.courseExtra,
// from
// )
// }
// }
// }
// adapter?.notifyDataSetChanged()
}
}
}
......
package com.yidianling.course.coursePlay.model
import com.ydl.ydlcommon.data.http.BaseResponse
import com.ydl.ydlcommon.mvp.base.BaseModel
import com.yidianling.course.bean.CourseMediaDetailBean
import com.yidianling.course.coursePlay.presenter.IAudioPlayContract
import com.yidianling.course.net.CourseRetrofitUtils
import io.reactivex.Observable
class AudioPlayModelImpl : BaseModel(), IAudioPlayContract.Model {
override fun getCoursePlayData(courseId: Int): Observable<BaseResponse<CourseMediaDetailBean>> {
return CourseRetrofitUtils.getCoursePlayData(courseId.toString())
}
}
\ No newline at end of file
package com.yidianling.course.coursePlay.presenter
import com.ydl.ydlcommon.data.http.BaseResponse
import com.ydl.ydlcommon.data.http.RxUtils
import com.ydl.ydlcommon.mvp.base.BasePresenter
import com.ydl.ydlnet.client.observer.CommonObserver
import com.yidianling.common.tools.ToastUtil
import com.yidianling.course.bean.CourseMediaDetailBean
import com.yidianling.course.coursePlay.model.AudioPlayModelImpl
class AudioPlayPresenter : BasePresenter<IAudioPlayContract.View, IAudioPlayContract.Model>(),
IAudioPlayContract.Presenter {
override fun createModel(): IAudioPlayContract.Model = AudioPlayModelImpl()
override fun getCoursePlayData(courseId: Int) {
mView.showProgressDialog()
mModel.getCoursePlayData(courseId)
.compose(RxUtils.applySchedulers())
.subscribe(object : CommonObserver<BaseResponse<CourseMediaDetailBean>>() {
override fun onError(s: String?) {
mView.dismissProgressDialog()
}
override fun onSuccess(resp: BaseResponse<CourseMediaDetailBean>?) {
mView.dismissProgressDialog()
resp?.let {
if (it.code == 200) {
//跟新view显示
if (it.data != null && it.data is CourseMediaDetailBean) {
mView.updateView(it.data as CourseMediaDetailBean)
} else {
ToastUtil.toastShort("解析出错")
}
} else {
ToastUtil.toastShort(it.msg)
}
}
}
})
}
}
\ No newline at end of file
package com.yidianling.course.coursePlay.presenter
import com.ydl.ydlcommon.data.http.BaseResponse
import com.ydl.ydlcommon.mvp.base.IModel
import com.ydl.ydlcommon.mvp.base.IPresenter
import com.ydl.ydlcommon.mvp.base.IView
import com.yidianling.course.bean.CourseMediaDetailBean
import io.reactivex.Observable
interface IAudioPlayContract {
interface View : IView {
fun showProgressDialog()
fun dismissProgressDialog()
fun updateView(bean: CourseMediaDetailBean)
}
interface Presenter : IPresenter<View> {
fun getCoursePlayData(courseId: Int)
}
interface Model : IModel {
fun getCoursePlayData(courseId: Int) : Observable<BaseResponse<CourseMediaDetailBean>>
}
}
\ No newline at end of file
......@@ -5,17 +5,16 @@ import android.app.Application
import android.content.Context
import android.content.Intent
import com.alibaba.android.arouter.facade.annotation.Route
import com.ydl.course.api.ICourseService
import com.ydl.media.audio.AudioPlayer
import com.ydl.media.view.PlayerFloatHelper
import com.ydl.course.api.ICourseService
import com.yidianling.course.courseNew.CourseTopicActivity
import com.yidianling.course.courseNew.mine.MyCourseActivity
import com.yidianling.course.coursePlay.AudioPlayActivity
import com.yidianling.course.coursePlay.CourseCommentActivity
import com.yidianling.course.coursePlay.CoursePlayActivity
import com.yidianling.course.coursePlay.CourseReplyListActivity
import com.yidianling.course.flutterPlugin.CourseSendPlugin
import com.yidianling.course.lifeCallback.CoursePlayLifecycle
import java.util.*
/**
* @author jiucheng
......@@ -61,7 +60,8 @@ class CourseServiceImp : ICourseService {
}
override fun startCoursePlayActivity(activity: Activity, courseId: Int, coursePlayUrl: String?, from: Int, mediaType: String?) {
val intent = Intent(activity, CoursePlayActivity::class.java)
// val intent = Intent(activity, CoursePlayActivity::class.java)
val intent = Intent(activity, AudioPlayActivity::class.java)
intent.putExtra("course_id", courseId)
intent.putExtra("coursePlayUrl", coursePlayUrl)
intent.putExtra("from", from)
......
package com.yidianling.course.widget
import android.content.Context
import android.text.TextUtils
import android.util.AttributeSet
import android.view.View
import android.widget.FrameLayout
import android.widget.SeekBar
import androidx.annotation.DrawableRes
import androidx.annotation.Nullable
import androidx.annotation.RawRes
import com.bumptech.glide.Glide
import com.ydl.media.audio.AudioPlayer
import com.ydl.media.audio.OnPlayerEventListener
import com.ydl.media.audio.enums.PlayModeEnum
import com.ydl.media.audio.model.Music
import com.ydl.media.view.PlayTypeEnum
import com.ydl.media.view.PlayerFloatHelper
import com.yidianling.common.tools.RxNetTool
import com.yidianling.course.R
import kotlinx.android.synthetic.main.audio_play_view.view.*
/**
* 音频播放UI
*/
class AudioPlayView(context: Context, attrs: AttributeSet?) :
FrameLayout(context, attrs), OnPlayerEventListener {
private var mSeekBarIsTouch = false
private var mProgress = 0
var mNonWifiTips = true
/**
* 切换前调用 -> 判断切换后 音频 是否符合业务条件
* 切换后调用 -> 若 音频 失效,自动切换至下一个,此时仍需判断是否符合业务条件
*/
var mListener: ((playPosition: Int) -> Unit)? = null
init {
AudioPlayer.get().addOnPlayEventListener(this)
View.inflate(context, R.layout.audio_play_view, this)
iv_bg.setOnClickListener {
AudioPlayer.get().playPause()
}
iv_rewind.setOnClickListener {
AudioPlayer.get().seekTo(position = AudioPlayer.get().currentPosition.minus(15000))
}
iv_fast_forward.setOnClickListener {
AudioPlayer.get().seekTo(position = AudioPlayer.get().currentPosition.plus(15000))
}
iv_pre.setOnClickListener {
mListener?.invoke(AudioPlayer.get().playPosition - 1)
}
iv_next.setOnClickListener {
mListener?.invoke(AudioPlayer.get().playPosition + 1)
}
seekbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
if (fromUser) {
tv_start.text = getStringTime(progress)
mProgress = progress
}
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {
mSeekBarIsTouch = true
}
override fun onStopTrackingTouch(seekBar: SeekBar?) {
mSeekBarIsTouch = false
//拖动seekbar时不进行以下操作
if (!mSeekBarIsTouch) {
AudioPlayer.get().seekTo(-1, mProgress.toLong())
}
}
})
}
fun setData(playPosition: Int, playList: ArrayList<Music>, isAuto: Boolean, from: Int) {
if (playList.isEmpty()) return
setAutoNext(isAuto)
AudioPlayer.get().addPlayList(playList)
if (AudioPlayer.get().isPlaying) mNonWifiTips = false
if (RxNetTool.isWifi(context)) {
playAudio(from, playPosition, playList)
} else {
if (mNonWifiTips) {
showNonWifiTips {
mNonWifiTips = false
playAudio(from, playPosition, playList)
}
} else {
playAudio(from, playPosition, playList)
}
}
}
private fun showNonWifiTips(block: () -> Unit) {
block.invoke()
}
private fun playAudio(from: Int, playPosition: Int, playList: ArrayList<Music>) {
if (AudioPlayer.get().isPlaying && (from == 1 || from == 2)) {
if (TextUtils.equals(getCurrentUrl(), playList[playPosition].path)) {
updateView(playPosition)
} else {
play(playPosition)
}
} else {
play(playPosition)
}
}
private fun updateView(playPosition: Int) {
if (AudioPlayer.get().isPlaying) {
seekbar.max = AudioPlayer.get().getDuration().toInt()
tv_end.text = getStringTime(seekbar.max)
if (AudioPlayer.get().isPlaying) {
displayPlayStatus(R.drawable.course_pause)
}
}
}
/**
* 获取当前播放url
*/
private fun getCurrentUrl(): String {
return AudioPlayer.get().playMusic?.path.orEmpty()
}
fun play(index: Int) {
PlayerFloatHelper.playingType = PlayTypeEnum.PLAY_TYPE_COURSE
AudioPlayer.get().play(index)
if (AudioPlayer.get().isPlaying) {
displayPlayStatus(R.drawable.course_pause)
}
}
/**
* 设置自动播放下一曲
*/
fun setAutoNext(auto: Boolean) {
if (!auto) {
AudioPlayer.get().playMode = PlayModeEnum.SINGLE
} else {
AudioPlayer.get().playMode = PlayModeEnum.LIST_LOOP
}
}
override fun onChange(music: Music) {
displayPlayStatus(R.drawable.course_loading5, true)
seekbar.progress = 0
tv_start.text = "00:00"
}
override fun onPlayerStart() {
displayPlayStatus(R.drawable.course_pause)
}
override fun onPlayerPause() {
if (AudioPlayer.get().isPlaying) {
displayPlayStatus(R.drawable.course_pause)
} else {
displayPlayStatus(R.drawable.course_play)
}
}
override fun onPublish(percent: Int, currentPosition: Long) {
if (!mSeekBarIsTouch) {
seekbar.progress = currentPosition.toInt()
tv_start.text = getStringTime(currentPosition.toInt())
}
}
override fun onBufferingUpdate(percent: Int) {
if (!AudioPlayer.get().isPlaying) {
displayPlayStatus(R.drawable.course_loading5, true)
}
seekbar.secondaryProgress = percent * seekbar.max / 100
}
override fun onPrepared(duration: Long) {
seekbar.max = duration.toInt()
tv_end.text = getStringTime(seekbar.max)
mListener?.invoke(AudioPlayer.get().playPosition)
}
override fun onComplete() {
if (AudioPlayer.get().isPlaying) {
displayPlayStatus(R.drawable.course_play)
}
}
private fun displayPlayStatus(
@RawRes @DrawableRes @Nullable resourceId: Int,
isGif: Boolean = false
) {
context?.let {
if (isGif) {
Glide.with(it).asGif().load(resourceId).into(iv_play_status)
} else {
Glide.with(it).asBitmap().load(resourceId).into(iv_play_status)
}
}
}
private fun getStringTime(time: Int): String {
if (time <= 0) return "00:00"
val min = time / 60000
val ss = (time - min * 60000) / 1000
var m = "" + min
var s = "" + ss
if (min < 10) {
m = "0$m"
}
if (ss < 10) {
s = "0$ss"
}
return "$m:$s"
}
fun onDestroy() {
AudioPlayer.get().removeOnPlayEventListener(this)
}
fun setSpeed(speed: Float) {
AudioPlayer.get().setSpeed(speed)
}
}
\ No newline at end of file
package com.yidianling.course.widget
import android.content.Context
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.ydl.media.audio.utils.PlayProgressUtil
import com.ydl.ydlcommon.base.BaseDialogFragment
import com.ydl.ydlcommon.utils.extend.gone
import com.ydl.ydlcommon.utils.extend.invisible
import com.ydl.ydlcommon.utils.extend.visible
import com.ydl.ydlcommon.view.dialog.CommonDialog
import com.yidianling.course.R
import com.yidianling.course.bean.CourseMediaBean
import kotlinx.android.synthetic.main.dialog_course_list.*
import kotlinx.android.synthetic.main.item_course_playlist.view.*
/**
* 课程目录弹窗
*/
class CourseListDialog : BaseDialogFragment() {
var mListener: CourseListListener? = null
var mCurrentPosition = 0
private var mAdapter: CourseListDialog.CourseListAdapter? = null
private val mCourseList = mutableListOf<CourseMediaBean>()
private var mIsBuy = false
override fun getLayoutResourceId(): Int = R.layout.dialog_course_list
override fun getGravity(): Int = Gravity.BOTTOM
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
context?.let { ctx ->
recycler_list.adapter = mAdapter ?: CourseListAdapter(ctx).also { mAdapter = it }
}
}
fun setData(isBuy: Boolean, currentPosition: Int, courseList: List<CourseMediaBean>) {
mIsBuy = isBuy
mCurrentPosition = currentPosition
mCourseList.clear()
mCourseList.addAll(courseList)
// mAdapter?.notifyDataSetChanged()
}
fun setCurrentPosition(currentPosition: Int) {
mCurrentPosition = currentPosition
// mAdapter?.notifyDataSetChanged()
}
inner class CourseListAdapter(
context: Context,
private val inflater: LayoutInflater = LayoutInflater.from(context)
) : RecyclerView.Adapter<CourseListAdapter.CourseListVH>() {
inner class CourseListVH(view: View) : RecyclerView.ViewHolder(view)
override fun onCreateViewHolder(p0: ViewGroup, itemType: Int): CourseListVH =
CourseListVH(inflater.inflate(R.layout.item_course_playlist, p0, false))
override fun onBindViewHolder(vh: CourseListVH, position: Int) {
mCourseList.elementAtOrNull(position)?.let { bean ->
vh.itemView.run {
if (mCurrentPosition == position) {
voice_play.visible()
voice_play.start()
iv_play.invisible()
// Glide.with(context).asGif()
// .load(R.drawable.course_music).into(gifView)
} else {
voice_play.gone()
voice_play.stop()
iv_play.visible()
if (mIsBuy) {
iv_play.setImageResource(R.drawable.course_play_orange)
} else {
if (bean.isDemo) {
iv_play.setImageResource(R.drawable.course_play_orange)
} else {
iv_play.setImageResource(R.drawable.course_play_lock)
}
}
}
tv_audition.visibility = if (bean.isDemo) View.VISIBLE else View.GONE // 试听标签
tv_title.text = bean.title
setOnClickListener {
if (mCurrentPosition == position) return@setOnClickListener
if (!bean.isDemo && !mIsBuy) {
CommonDialog(context)
.setMessage("\n购买课程,获取完整课程内容\n")
.setLeftOnclick("放弃") {}
.setRightClick("购买") {
//跳转支付页
mListener?.addCourseOrder()
}
.setCancelAble(false)
.show()
} else {
PlayProgressUtil.saveProgress(
context,
mCourseList.elementAtOrNull(position)?.url,
0
)
mCurrentPosition = position
notifyDataSetChanged()
mListener?.togglePlaying(position)
dismissAllowingStateLoss()
}
}
}
}
}
override fun getItemCount(): Int = mCourseList.size
}
}
interface CourseListListener {
fun addCourseOrder()
fun togglePlaying(position: Int)
}
\ No newline at end of file
package com.yidianling.course.widget
import android.content.Context
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import androidx.recyclerview.widget.RecyclerView
import com.ydl.ydlcommon.base.BaseDialogFragment
import com.yidianling.course.R
import kotlinx.android.synthetic.main.dialog_course_speed.*
import kotlinx.android.synthetic.main.item_course_speed.view.*
/**
* 课程倍速dialog
*/
class CourseSpeedDialog : BaseDialogFragment() {
var mListener: ((speed: Float) -> Unit)? = null
private var mAdapter: CourseSpeedAdapter? = null
override fun getLayoutResourceId(): Int = R.layout.dialog_course_speed
override fun getGravity(): Int = Gravity.BOTTOM
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
context?.let {
if (null == mAdapter) mAdapter = CourseSpeedAdapter(it)
recycler_list.adapter = mAdapter
tv_cancel.setOnClickListener {
dismissAllowingStateLoss()
}
}
}
inner class CourseSpeedAdapter(
context: Context,
private val inflater: LayoutInflater = LayoutInflater.from(context)
) : RecyclerView.Adapter<CourseSpeedAdapter.CourseSpeedVH>() {
private val mSpeedList = floatArrayOf(0.5f, 0.75f, 1.0f, 1.25f, 1.5f, 2.0f, 3.0f)
private var mOldPosition = -1
private var mCurrentPosition = 2
inner class CourseSpeedVH(view: View) : RecyclerView.ViewHolder(view)
override fun onCreateViewHolder(viewGroup: ViewGroup, itemType: Int): CourseSpeedVH =
CourseSpeedVH(inflater.inflate(R.layout.item_course_speed, viewGroup, false))
override fun onBindViewHolder(vh: CourseSpeedVH, position: Int) {
vh.itemView.let {
mSpeedList.elementAtOrNull(position)?.let { speed ->
it.tv_speed.run {
setTextColor(resources.getColor(if (position == mCurrentPosition) R.color.color_1DA1F2 else R.color.color_1C1F28))
text = speed.toString()
setOnClickListener {
if (position == mCurrentPosition) {
dismissAllowingStateLoss()
return@setOnClickListener
}
mOldPosition = mCurrentPosition
mCurrentPosition = position
notifyItemChanged(mOldPosition)
notifyItemChanged(mCurrentPosition)
mListener?.invoke(speed)
dismissAllowingStateLoss()
}
}
}
}
}
override fun getItemCount(): Int = mSpeedList.size
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke android:color="@color/color_EB892C" android:width="1dp"/>
<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">
<corners android:topLeftRadius="8dp"
android:topRightRadius="8dp"/>
<solid android:color="@android:color/white"/>
</shape>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M0,0h24v24h-24z"
android:strokeAlpha="0"
android:strokeWidth="1"
android:fillColor="#D8D8D8"
android:fillType="evenOdd"
android:strokeColor="#00000000"
android:fillAlpha="0"/>
<path
android:pathData="M14.2,5l-7.2,7.1111l7.2,7.1111"
android:strokeLineJoin="round"
android:strokeWidth="1.8"
android:fillColor="#00000000"
android:strokeColor="#FFFFFF"
android:fillType="evenOdd"
android:strokeLineCap="round"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="35dp"
android:height="35dp"
android:viewportWidth="35"
android:viewportHeight="35">
<path
android:pathData="M0.5,0.5h34v34h-34z"
android:strokeAlpha="0"
android:strokeWidth="1"
android:fillColor="#D8D8D8"
android:fillType="evenOdd"
android:strokeColor="#00000000"
android:fillAlpha="0"/>
<path
android:pathData="M7.9527,17.7392C8.0227,17.2311 8.5559,15.0407 8.8424,14.2479C10.2325,10.4007 13.8216,7.8959 17.7361,7.895C19.5587,7.895 21.2717,8.4306 22.7243,9.3859L21.8473,9.3859C21.0936,9.3859 20.4769,10.0373 20.4769,10.8334C20.4769,11.6295 21.0936,12.2808 21.8473,12.2808L25.9584,12.2808C26.7121,12.2808 27.3288,11.6295 27.3288,10.8334L27.3288,6.491C27.3288,5.6963 26.7121,5.045 25.9584,5.045C25.2047,5.045 24.588,5.6963 24.588,6.4924L24.588,7.2017C22.5627,5.7633 20.1767,4.9967 17.7361,5C14.7624,5 12.0354,6.1147 9.9127,7.9819L9.899,7.9819C9.5975,8.2569 9.296,8.5464 9.0082,8.8503C8.7204,9.1398 8.4738,9.4293 8.2271,9.7478C8.186,9.8057 8.1449,9.8491 8.1038,9.907C7.9941,10.0662 7.8845,10.211 7.7886,10.3557C7.6652,10.5294 7.5419,10.7176 7.4323,10.8913C7.3089,11.0794 7.1993,11.2676 7.0897,11.4558C7.0075,11.6439 6.9115,11.8176 6.8156,12.0058C6.706,12.2084 6.61,12.4256 6.5141,12.6268C6.4456,12.8005 6.3771,12.9886 6.3086,13.1623C6.1578,13.5531 6.0208,13.944 5.9112,14.3492C5.8015,14.7545 5.2381,16.5044 5.2381,17.9926C5.3407,18.6628 5.8122,18.9979 6.6529,18.9979C7.5775,18.9979 7.798,18.864 7.9527,17.7392ZM28.6443,17.8422L28.78,17.8506C29.4827,17.9327 30,18.3696 30,19.3126C29.9998,22.3763 26.9954,28.6181 22.7275,29.9085C21.9104,30.168 21.353,29.8757 21.0553,29.0315C20.7577,28.1874 21.021,27.5571 21.8454,27.1406C25.2123,24.9129 26.2524,23.9403 27.2726,19.1403C27.2726,18.7152 27.4881,18.4055 27.7714,18.1634C28.0546,17.9213 28.4179,17.8092 28.78,17.8506ZM19.9882,19.9111L19.9882,21.3425L17.2499,21.3425L17.2499,22.4064C17.3204,22.3548 17.4389,22.2968 17.6054,22.2323C17.772,22.1678 17.9609,22.1356 18.1723,22.1356C18.4733,22.1356 18.7343,22.1807 18.9553,22.271C19.1763,22.3613 19.3573,22.4773 19.4982,22.6192C19.6391,22.7611 19.7512,22.9045 19.8344,23.0496C19.9177,23.1947 19.9818,23.3446 20.0266,23.4993C20.0714,23.6541 20.1003,23.8105 20.1131,23.9684C20.1259,24.1264 20.1323,24.286 20.1323,24.4472C20.1323,24.6535 20.1227,24.8405 20.1035,25.0082C20.0842,25.1758 20.0506,25.3322 20.0026,25.4773C19.9545,25.6223 19.8905,25.7577 19.8104,25.8835C19.7304,26.0092 19.6263,26.1366 19.4982,26.2655C19.3508,26.4138 19.1459,26.5492 18.8833,26.6717C18.6207,26.7942 18.2972,26.8555 17.9129,26.8555C17.5286,26.8555 17.1987,26.7926 16.9233,26.6669C16.6479,26.5412 16.4365,26.4041 16.2892,26.2558C16.0458,26.0108 15.8904,25.7529 15.8232,25.4821C15.7559,25.2113 15.7127,24.9501 15.6935,24.6987L15.6935,24.6987L17.2692,24.6987C17.2948,24.9243 17.3572,25.1017 17.4565,25.2306C17.5558,25.3596 17.7079,25.4241 17.9129,25.4241C18.0922,25.4241 18.2395,25.366 18.3548,25.25C18.4893,25.1146 18.5566,24.847 18.5566,24.4472C18.5566,24.0668 18.4974,23.8088 18.3789,23.6734C18.2604,23.538 18.105,23.4703 17.9129,23.4703C17.7976,23.4703 17.7031,23.4881 17.6294,23.5235C17.5558,23.559 17.4949,23.6009 17.4469,23.6493C17.3989,23.6976 17.362,23.7508 17.3364,23.8088C17.3108,23.8669 17.2884,23.9185 17.2692,23.9636L17.2692,23.9636L15.8184,23.9636L15.8184,19.9111L19.9882,19.9111ZM13.7719,19.9111L13.7719,26.7975L12.1962,26.7975L12.1962,21.6036L10.7359,22.8803L10.7359,21.1878L12.1962,19.9111L13.7719,19.9111ZM7.94,21.7294L7.94,23.1995L9.4004,23.1995L9.4004,24.689L7.94,24.689L7.94,26.1591L6.4604,26.1591L6.4604,24.689L5,24.689L5,23.1995L6.4604,23.1995L6.4604,21.7294L7.94,21.7294Z"
android:strokeAlpha="0.9049247"
android:strokeWidth="1"
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:strokeColor="#00000000"
android:fillAlpha="0.9049247"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="25dp"
android:height="25dp"
android:viewportWidth="25"
android:viewportHeight="25">
<path
android:pathData="M0.5,0.5h24v24h-24z"
android:strokeAlpha="0"
android:strokeWidth="1"
android:fillColor="#D8D8D8"
android:fillType="evenOdd"
android:strokeColor="#00000000"
android:fillAlpha="0"/>
<path
android:pathData="M19.5,5.5L19.5,19.5"
android:strokeWidth="1.5"
android:fillColor="#00000000"
android:strokeColor="#ffffff"
android:fillType="evenOdd"
android:strokeLineCap="round"/>
<path
android:pathData="M16.9844,12.109C17.0845,12.676 16.9682,13.2813 16.6119,13.7903C16.4613,14.0055 16.2741,14.1926 16.0589,14.3433L16.0589,14.3433L7.7168,20.1827C7.434,20.3807 7.0978,20.4453 6.7828,20.3897C6.4677,20.3341 6.1739,20.1583 5.976,19.8755C5.8289,19.6654 5.75,19.4152 5.75,19.1587L5.75,19.1587L5.75,5.8413C5.75,5.4961 5.8899,5.1836 6.1161,4.9574C6.3423,4.7312 6.6548,4.5913 7,4.5913C7.2565,4.5913 7.5067,4.6702 7.7168,4.8173L7.7168,4.8173L16.0589,10.6567C16.5679,11.013 16.8843,11.5419 16.9844,12.109Z"
android:strokeWidth="1.5"
android:fillColor="#00000000"
android:strokeColor="#ffffff"
android:fillType="evenOdd"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="30dp"
android:height="30dp"
android:viewportWidth="30"
android:viewportHeight="30">
<path
android:pathData="M0,0h30v30h-30z"
android:strokeAlpha="0"
android:strokeWidth="1"
android:fillColor="#D8D8D8"
android:fillType="evenOdd"
android:strokeColor="#00000000"
android:fillAlpha="0"/>
<path
android:pathData="M10.9611,22.8393C10.9611,24.0338 10.074,25 8.9805,25C7.8871,25 7,24.0338 7,22.8393L7,7.1607C7,5.9662 7.8871,5 8.9805,5C10.074,5 10.9611,5.9662 10.9611,7.1607L10.9611,22.8393ZM23,22.8393C23,24.0338 22.1129,25 21.0195,25C19.926,25 19.0389,24.0338 19.0389,22.8393L19.0389,7.1607C19.0389,5.9662 19.926,5 21.0195,5C22.1129,5 23,5.9662 23,7.1607L23,22.8393Z"
android:strokeWidth="1"
android:fillColor="#1C1F28"
android:fillType="nonZero"
android:strokeColor="#00000000"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="30dp"
android:height="30dp"
android:viewportWidth="30"
android:viewportHeight="30">
<path
android:pathData="M0,0h30v30h-30z"
android:strokeAlpha="0"
android:strokeWidth="1"
android:fillColor="#D8D8D8"
android:fillType="evenOdd"
android:strokeColor="#00000000"
android:fillAlpha="0"/>
<path
android:pathData="M22.5558,15.1804C22.6559,15.7475 22.5396,16.3527 22.1833,16.8617C22.0327,17.0769 21.8455,17.2641 21.6303,17.4147L21.6303,17.4147L11.1454,24.7542C10.8626,24.9521 10.5264,25.0167 10.2113,24.9611C9.8963,24.9055 9.6025,24.7297 9.4045,24.4469C9.2575,24.2368 9.1786,23.9866 9.1786,23.7301L9.1786,23.7301L9.1786,7.4127C9.1786,7.0676 9.3185,6.7551 9.5447,6.5289C9.7709,6.3027 10.0834,6.1627 10.4286,6.1627C10.685,6.1627 10.9353,6.2416 11.1454,6.3887L11.1454,6.3887L21.6303,13.7282C22.1393,14.0845 22.4557,14.6133 22.5558,15.1804Z"
android:strokeWidth="1.5"
android:fillColor="#1C1F28"
android:strokeColor="#1C1F28"
android:fillType="evenOdd"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M0,0h24v24h-24z"
android:strokeAlpha="0"
android:strokeWidth="1"
android:fillColor="#D8D8D8"
android:fillType="evenOdd"
android:strokeColor="#00000000"
android:fillAlpha="0"/>
<path
android:pathData="M12,14m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"
android:strokeWidth="1.5"
android:fillColor="#00000000"
android:strokeColor="#242424"
android:fillType="evenOdd"/>
<path
android:pathData="M17,9C17,6.2386 14.7614,4 12,4C9.2386,4 7,6.2386 7,9"
android:strokeWidth="1.5"
android:fillColor="#00000000"
android:strokeColor="#242424"
android:fillType="evenOdd"/>
<path
android:pathData="M7.75,8.75L16.25,8.75A3,3 0,0 1,19.25 11.75L19.25,16.25A3,3 0,0 1,16.25 19.25L7.75,19.25A3,3 0,0 1,4.75 16.25L4.75,11.75A3,3 0,0 1,7.75 8.75z"
android:strokeWidth="1.5"
android:fillColor="#00000000"
android:strokeColor="#242424"
android:fillType="evenOdd"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="25dp"
android:height="25dp"
android:viewportWidth="25"
android:viewportHeight="25">
<path
android:pathData="M0.5,0.5h24v24h-24z"
android:strokeAlpha="0"
android:strokeWidth="1"
android:fillColor="#D8D8D8"
android:fillType="evenOdd"
android:strokeColor="#00000000"
android:fillAlpha="0"/>
<path
android:pathData="M5.5,5.5L5.5,19.5"
android:strokeWidth="1.5"
android:fillColor="#00000000"
android:strokeColor="#ffffff"
android:fillType="evenOdd"
android:strokeLineCap="round"/>
<path
android:pathData="M8.0156,12.109C7.9155,12.676 8.0318,13.2813 8.3881,13.7903C8.5387,14.0055 8.7259,14.1926 8.9411,14.3433L8.9411,14.3433L17.2832,20.1827C17.566,20.3807 17.9022,20.4453 18.2172,20.3897C18.5323,20.3341 18.8261,20.1583 19.024,19.8755C19.1711,19.6654 19.25,19.4152 19.25,19.1587L19.25,19.1587L19.25,5.8413C19.25,5.4961 19.1101,5.1836 18.8839,4.9574C18.6577,4.7312 18.3452,4.5913 18,4.5913C17.7435,4.5913 17.4933,4.6702 17.2832,4.8173L17.2832,4.8173L8.9411,10.6567C8.4321,11.013 8.1157,11.5419 8.0156,12.109Z"
android:strokeWidth="1.5"
android:fillColor="#00000000"
android:strokeColor="#ffffff"
android:fillType="evenOdd"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="35dp"
android:height="35dp"
android:viewportWidth="35"
android:viewportHeight="35">
<path
android:pathData="M0.5,0.5h34v34h-34z"
android:strokeAlpha="0"
android:strokeWidth="1"
android:fillColor="#D8D8D8"
android:fillType="evenOdd"
android:strokeColor="#00000000"
android:fillAlpha="0"/>
<path
android:pathData="M27.1712,17.7392C27.1008,17.2311 26.5646,15.0407 26.2765,14.2479C24.8785,10.4007 21.2694,7.8959 17.3328,7.895C15.4999,7.895 13.7773,8.4306 12.3166,9.3859L13.1985,9.3859C13.9565,9.3859 14.5766,10.0373 14.5766,10.8334C14.5766,11.6295 13.9565,12.2808 13.1985,12.2808L9.0643,12.2808C8.3064,12.2808 7.6862,11.6295 7.6862,10.8334L7.6862,6.491C7.6862,5.6963 8.3064,5.045 9.0643,5.045C9.8223,5.045 10.4424,5.6963 10.4424,6.4924L10.4424,7.2017C12.4791,5.7633 14.8785,4.9967 17.3328,5C20.3232,5 23.0656,6.1147 25.2002,7.9819L25.214,7.9819C25.5172,8.2569 25.8204,8.5464 26.1098,8.8503C26.3992,9.1398 26.6472,9.4293 26.8953,9.7478C26.9366,9.8057 26.9779,9.8491 27.0193,9.907C27.1295,10.0662 27.2398,10.211 27.3362,10.3557C27.4603,10.5294 27.5843,10.7176 27.6945,10.8913C27.8186,11.0794 27.9288,11.2676 28.0391,11.4558C28.1218,11.6439 28.2182,11.8176 28.3147,12.0058C28.4249,12.2084 28.5214,12.4256 28.6179,12.6268C28.6868,12.8005 28.7557,12.9886 28.8246,13.1623C28.9762,13.5531 29.114,13.944 29.2242,14.3492C29.3345,14.7545 29.9011,16.5044 29.9011,17.9926C29.7979,18.6628 29.3237,18.9979 28.4783,18.9979C27.5485,18.9979 27.3268,18.864 27.1712,17.7392ZM12.3134,29.9085C8.0215,28.6181 5.0002,22.3763 5,19.3126C5,18.3696 5.5202,17.9327 6.2268,17.8506C6.591,17.8092 6.9563,17.9213 7.2412,18.1634C7.526,18.4055 7.7427,18.7152 7.7427,19.1403C8.7687,23.9403 9.8146,24.9129 13.2004,27.1406C14.0294,27.5571 14.2943,28.1874 13.9949,29.0315C13.6956,29.8757 13.1351,30.168 12.3134,29.9085Z"
android:strokeAlpha="0.9007859"
android:strokeWidth="1"
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:strokeColor="#00000000"
android:fillAlpha="0.9007859"/>
<path
android:pathData="M19.3062,26.4446L19.3062,24.9551L16.1661,24.9551L16.1661,26.4446L19.3062,26.4446ZM23.6622,28.5531L23.6622,21.6667L22.0922,21.6667L20.637,22.9434L20.637,24.636L22.0922,23.3593L22.0922,28.5531L23.6622,28.5531ZM27.7885,28.6111C28.1714,28.6111 28.4937,28.5499 28.7554,28.4273C29.0171,28.3048 29.2213,28.1694 29.3681,28.0211C29.4958,27.8922 29.5995,27.7648 29.6793,27.6391C29.7591,27.5133 29.8229,27.3779 29.8708,27.2329C29.9186,27.0878 29.9521,26.9314 29.9713,26.7638C29.9904,26.5961 30,26.4091 30,26.2028C30,26.0416 29.9936,25.882 29.9809,25.724C29.9681,25.5661 29.9394,25.4097 29.8947,25.255C29.85,25.1002 29.7862,24.9503 29.7032,24.8052C29.6202,24.6601 29.5086,24.5167 29.3681,24.3748C29.2277,24.233 29.0474,24.1169 28.8272,24.0266C28.607,23.9363 28.347,23.8912 28.047,23.8912C27.8364,23.8912 27.6481,23.9235 27.4821,23.9879C27.3162,24.0524 27.1981,24.1104 27.1279,24.162L27.1279,23.0981L29.8564,23.0981L29.8564,21.6667L25.7014,21.6667L25.7014,25.7192L27.1471,25.7192C27.1662,25.6741 27.1885,25.6225 27.2141,25.5645C27.2396,25.5064 27.2763,25.4532 27.3242,25.4049C27.372,25.3565 27.4327,25.3146 27.5061,25.2791C27.5795,25.2437 27.6736,25.2259 27.7885,25.2259C27.98,25.2259 28.1347,25.2936 28.2528,25.429C28.3709,25.5645 28.4299,25.8224 28.4299,26.2028C28.4299,26.6026 28.3629,26.8702 28.2289,27.0056C28.114,27.1216 27.9672,27.1797 27.7885,27.1797C27.5842,27.1797 27.4327,27.1152 27.3337,26.9862C27.2348,26.8573 27.1726,26.68 27.1471,26.4543L25.577,26.4543C25.5961,26.7057 25.6392,26.9669 25.7062,27.2377C25.7732,27.5085 25.928,27.7664 26.1705,28.0115C26.3173,28.1598 26.528,28.2968 26.8024,28.4225C27.0768,28.5482 27.4055,28.6111 27.7885,28.6111Z"
android:strokeAlpha="0.9007859"
android:strokeWidth="1"
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:strokeColor="#00000000"
android:fillAlpha="0.9007859"/>
</vector>
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="3dp" />
<solid android:color="@color/color_FAFAFF" />
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<corners android:radius="3dp" />
<solid android:color="#ECF0F1" />
</shape>
</clip>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="3dp" />
<solid android:color="@color/color_1DA1F2" />
</shape>
</clip>
</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">
<size
android:width="17dp"
android:height="17dp" />
<stroke android:color="@color/white" android:width="6dp"/>
<solid android:color="@color/color_1DA1F2" />
</shape>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M10.7744,4C6.94,4.5762 4,7.8845 4,11.8796C4,16.2804 7.5676,19.848 11.9684,19.848C15.9614,19.848 19.2685,16.9109 19.8471,13.0793"
android:strokeLineJoin="round"
android:strokeWidth="1.8"
android:fillColor="#00000000"
android:strokeColor="#FFFFFF"
android:fillType="evenOdd"
android:strokeLineCap="round"/>
<path
android:pathData="M11.6696,12.1744L18.642,5.202"
android:strokeLineJoin="round"
android:strokeWidth="1.8"
android:fillColor="#00000000"
android:strokeColor="#FFFFFF"
android:fillType="evenOdd"
android:strokeLineCap="round"/>
<path
android:pathData="M15.6538,4.206L19.14,4.206C19.415,4.206 19.638,4.4289 19.638,4.704L19.638,8.1946"
android:strokeLineJoin="round"
android:strokeWidth="1.8"
android:fillColor="#00000000"
android:strokeColor="#FFFFFF"
android:fillType="evenOdd"
android:strokeLineCap="round"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="12dp"
android:height="12dp"
android:viewportWidth="12"
android:viewportHeight="12">
<path
android:pathData="M0,0h12v12h-12z"
android:strokeAlpha="0"
android:strokeWidth="1"
android:fillColor="#D8D8D8"
android:fillType="evenOdd"
android:strokeColor="#00000000"
android:fillAlpha="0"/>
<path
android:pathData="M6,6m-4.6,0a4.6,4.6 0,1 1,9.2 0a4.6,4.6 0,1 1,-9.2 0"
android:strokeWidth="0.8"
android:fillColor="#00000000"
android:strokeColor="#979797"
android:fillType="evenOdd"/>
<path
android:pathData="M5.9724,3.5028L5.9724,6.1028"
android:strokeWidth="0.8"
android:fillColor="#00000000"
android:strokeColor="#979797"
android:fillType="evenOdd"
android:strokeLineCap="round"/>
<path
android:pathData="M6.0724,6.1028L8.6724,6.1028"
android:strokeWidth="0.8"
android:fillColor="#00000000"
android:strokeColor="#979797"
android:fillType="evenOdd"
android:strokeLineCap="round"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="375dp"
android:height="90dp"
android:viewportWidth="375"
android:viewportHeight="90">
<path
android:pathData="M0,0h375v90h-375z"
android:strokeWidth="1"
android:fillType="evenOdd"
android:strokeColor="#00000000">
<aapt:attr name="android:fillColor">
<gradient
android:startY="0"
android:startX="187.5"
android:endY="90"
android:endX="187.5"
android:type="linear">
<item android:offset="0" android:color="#C7FFFFFF"/>
<item android:offset="0.45317963" android:color="#FFFFFFFF"/>
<item android:offset="1" android:color="#FFFFFFFF"/>
</gradient>
</aapt:attr>
</path>
</vector>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/cl_bg"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:background="#9F998F">
<ImageView
android:id="@+id/iv_back"
android:layout_width="36dp"
android:layout_height="36dp"
android:paddingStart="12dp"
android:paddingTop="12dp"
android:src="@drawable/course_back"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/iv_share"
android:layout_width="36dp"
android:layout_height="0dp"
android:paddingEnd="12dp"
android:src="@drawable/course_share"
app:layout_constraintEnd_toEndOf="parent"
android:paddingTop="12dp"
app:layout_constraintTop_toTopOf="@id/iv_back"
app:layout_constraintBottom_toBottomOf="@id/iv_back"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/iv_back">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv_pic"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="34dp"
android:layout_marginTop="28dp"
android:layout_marginEnd="34dp"
android:scaleType="fitXY"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/picture_album_bg" />
<TextView
android:id="@+id/tv_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="32dp"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@android:color/white"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/iv_pic"
tools:text="关注孩子心理健康,18天带领孩子1111111111" />
<androidx.constraintlayout.utils.widget.ImageFilterView
android:id="@+id/iv_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="33dp"
android:layout_marginTop="15dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title"
app:roundPercent="1"
tools:src="@drawable/picture_album_bg" />
<TextView
android:id="@+id/tv_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:textColor="@android:color/white"
android:textSize="13sp"
app:layout_constraintBottom_toBottomOf="@id/iv_icon"
app:layout_constraintStart_toEndOf="@id/iv_icon"
app:layout_constraintTop_toTopOf="@id/iv_icon"
tools:text="你好啊" />
<ImageView
android:id="@+id/iv_detail"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginTop="56dp"
android:src="@drawable/course_detail"
app:layout_constraintEnd_toStartOf="@id/iv_speed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_name" />
<ImageView
android:id="@+id/iv_speed"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/course_speed"
app:layout_constraintEnd_toStartOf="@id/iv_list"
app:layout_constraintStart_toEndOf="@id/iv_detail"
app:layout_constraintTop_toTopOf="@id/iv_detail" />
<ImageView
android:id="@+id/iv_list"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/course_list"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/iv_speed"
app:layout_constraintTop_toTopOf="@id/iv_detail" />
<TextView
android:id="@+id/tv_detail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="7dp"
android:text="详情"
android:textColor="@android:color/white"
android:textSize="13sp"
app:layout_constraintEnd_toStartOf="@id/tv_speed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/iv_detail" />
<TextView
android:id="@+id/tv_speed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="7dp"
android:text="倍速"
android:textColor="@android:color/white"
android:textSize="13sp"
app:layout_constraintEnd_toStartOf="@id/tv_list"
app:layout_constraintStart_toEndOf="@id/tv_detail"
app:layout_constraintTop_toTopOf="@id/tv_detail" />
<TextView
android:id="@+id/tv_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="7dp"
android:text="列表"
android:textColor="@android:color/white"
android:textSize="13sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/tv_speed"
app:layout_constraintTop_toTopOf="@id/tv_detail" />
<com.yidianling.course.widget.AudioPlayView
android:id="@+id/audio_play"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="28dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_detail" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:background="#9F998F">
<ImageView
android:id="@+id/iv_rewind"
android:layout_width="25dp"
android:layout_height="25dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:src="@drawable/course_rewind_15"/>
<ImageView
android:id="@+id/iv_fast_forward"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/course_fast_forward_15"/>
<SeekBar
android:id="@+id/seekbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@id/iv_rewind"
app:layout_constraintEnd_toStartOf="@id/iv_fast_forward"
app:layout_constraintTop_toTopOf="@id/iv_rewind"
app:layout_constraintBottom_toBottomOf="@id/iv_rewind"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:maxHeight="3dp"
android:minHeight="3dp"
android:progressDrawable="@drawable/course_seekbar"
android:thumb="@drawable/course_seekbar_dot"
tools:progress="0" />
<TextView
android:id="@+id/tv_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="00:00"
android:textSize="12sp"
app:layout_constraintStart_toStartOf="@id/seekbar"
app:layout_constraintTop_toBottomOf="@id/seekbar"
android:textColor="@android:color/white"/>
<TextView
android:id="@+id/tv_end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="00:00"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="@id/seekbar"
app:layout_constraintTop_toBottomOf="@id/seekbar"
android:textColor="@android:color/white"/>
<androidx.constraintlayout.utils.widget.ImageFilterView
android:id="@+id/iv_bg"
android:layout_width="66dp"
android:layout_height="66dp"
app:roundPercent="1"
android:layout_marginTop="20dp"
app:layout_constraintTop_toBottomOf="@id/tv_start"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:background="@android:color/white"/>
<ImageView
android:id="@+id/iv_play_status"
android:layout_width="30dp"
android:layout_height="30dp"
app:layout_constraintTop_toTopOf="@id/iv_bg"
app:layout_constraintBottom_toBottomOf="@id/iv_bg"
app:layout_constraintStart_toStartOf="@id/iv_bg"
app:layout_constraintEnd_toEndOf="@id/iv_bg"
tools:src="@drawable/course_play"/>
<ImageView
android:id="@+id/iv_pre"
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:layout_marginEnd="36dp"
app:layout_constraintTop_toTopOf="@id/iv_bg"
app:layout_constraintBottom_toBottomOf="@id/iv_bg"
app:layout_constraintEnd_toStartOf="@id/iv_bg"
android:src="@drawable/course_pre"/>
<ImageView
android:id="@+id/iv_next"
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:layout_marginStart="36dp"
app:layout_constraintStart_toEndOf="@id/iv_bg"
app:layout_constraintTop_toTopOf="@id/iv_bg"
app:layout_constraintBottom_toBottomOf="@id/iv_bg"
android:src="@drawable/course_next"/>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_top_corner">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="播放列表"
android:textColor="@color/color_1C1F28"
android:textSize="16dp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_list"
android:layout_width="match_parent"
android:layout_height="500dp"
android:layout_marginTop="12dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintTop_toBottomOf="@id/tv_title" />
<View
android:layout_width="match_parent"
android:layout_height="55dp"
android:background="@drawable/mask"
app:layout_constraintBottom_toBottomOf="@id/recycler_list" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_top_corner"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
<View
android:layout_width="match_parent"
android:layout_height="8dp"
android:background="@color/color_FAFAFB" />
<TextView
android:id="@+id/tv_cancel"
android:layout_width="match_parent"
android:layout_height="55dp"
android:text="取消"
android:background="@android:color/white"
android:gravity="center"
android:textStyle="bold"
android:textColor="@color/color_1C1F28"
android:textSize="18sp"/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingTop="16dp"
android:paddingEnd="11dp">
<TextView
android:id="@+id/tv_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_1C1F28"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="01" />
<TextView
android:id="@+id/tv_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="11dp"
android:ellipsize="end"
android:maxLines="1"
android:paddingTop="1dp"
android:textColor="@color/color_1C1F28"
android:textSize="14sp"
app:layout_constraintEnd_toStartOf="@id/iv_play"
app:layout_constraintStart_toEndOf="@id/tv_num"
app:layout_constraintTop_toTopOf="parent"
tools:text="孩子是厌学情绪,还是厌学症?孩子是厌学情绪,还是厌学症?" />
<com.yidianling.common.view.ui.VoicePlayingIcon
android:id="@+id/voice_play"
android:layout_width="15dp"
android:layout_height="16dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="2dp"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:pointer_color="@color/color_1DA1F2"
app:pointer_num="3"
app:pointer_width="3"
app:pointer_speed="10"/>
<ImageView
android:id="@+id/iv_play"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="2dp"
tools:src="@drawable/course_play_orange"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_audition"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:background="@drawable/bg_stroke_eb892c"
android:paddingStart="8dp"
android:paddingTop="1dp"
android:paddingEnd="8dp"
android:visibility="gone"
tools:visibility="visible"
android:paddingBottom="1dp"
android:text="试听"
android:textColor="@color/color_EB892C"
android:textSize="12sp"
app:layout_constraintStart_toStartOf="@id/tv_title"
app:layout_constraintTop_toBottomOf="@id/tv_title" />
<!-- <ImageView-->
<!-- android:id="@+id/iv_surface"-->
<!-- android:layout_width="10dp"-->
<!-- android:layout_height="10dp"-->
<!-- android:layout_marginStart="12dp"-->
<!-- android:src="@drawable/course_surface"-->
<!-- app:layout_constraintBottom_toBottomOf="@id/tv_duration"-->
<!-- app:layout_constraintStart_toEndOf="@id/tv_audition"-->
<!-- app:layout_constraintTop_toTopOf="@id/tv_duration"-->
<!-- app:layout_goneMarginStart="0dp" />-->
<!-- <TextView-->
<!-- android:id="@+id/tv_duration"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginStart="4dp"-->
<!-- android:textColor="@color/color_9D9EA7"-->
<!-- android:textSize="12sp"-->
<!-- android:layout_marginTop="8dp"-->
<!-- app:layout_constraintStart_toEndOf="@id/iv_surface"-->
<!-- app:layout_constraintTop_toBottomOf="@id/tv_title"-->
<!-- tools:text="08:32" />-->
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="28dp"
android:layout_marginEnd="5dp"
android:background="@color/color_EFEFF1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/iv_play" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/tv_speed"
android:textColor="@color/color_1C1F28"
tools:text="2.0"
android:gravity="center"
android:textSize="16sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp" />
\ No newline at end of file
......@@ -13,7 +13,7 @@ import com.ydl.webview.H5Params;
import com.ydl.webview.NewH5Activity;
import com.ydl.ydl_image.module.GlideApp;
import com.ydl.ydl_image.transform.GlideCircleTransform;
import com.ydl.ydlcommon.base.BaseDialogFragment;
import com.ydl.ydlcommon.base.BaseOldDialogFragment;
import com.ydl.ydlcommon.bean.ShareData;
import com.ydl.ydlcommon.view.dialog.CommonDialog;
import com.yidianling.common.tools.ToastUtil;
......@@ -30,7 +30,7 @@ import io.reactivex.schedulers.Schedulers;
/**
* Created by jinkai on 16/5/10.
*/
public class ShowIntroduceDialogFragment extends BaseDialogFragment {
public class ShowIntroduceDialogFragment extends BaseOldDialogFragment {
private ImageView mHead;
......
......@@ -425,7 +425,7 @@ public class FMDetailActivity extends BaseActivity implements View.OnClickListen
iv_play.setImageResource(R.drawable.fm_stop_2);
fm_progress.setProgress(0);
}else {
this.time = Integer.parseInt(String.valueOf(AudioPlayer.Companion.get().getAudioPosition()));
this.time = Integer.parseInt(String.valueOf(AudioPlayer.Companion.get().getCurrentPosition()));
//PlayProgressUtil.INSTANCE.getProgress(this, fmDetail.getFm_url());
updateThread();
}
......
......@@ -71,7 +71,7 @@ class MusePlugin : MethodChannel.MethodCallHandler {
var mContinue: Boolean = methodCall.argument<Boolean>("mContinue")!!
if (mContinue) {
AudioPlayer.get().seekTo(-1, AudioPlayer.get().audioPosition)
AudioPlayer.get().seekTo(-1, AudioPlayer.get().currentPosition)
AudioPlayer.get().startPlayer()
}else {
val music = Music()
......
......@@ -7,7 +7,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.DatePicker;
import com.ydl.ydlcommon.base.BaseDialogFragment;
import com.ydl.ydlcommon.base.BaseOldDialogFragment;
import com.yidianling.user.R;
import java.util.Calendar;
......@@ -17,7 +17,7 @@ import java.util.Calendar;
* 日期选择器 dialog
* Created by Dog on 2015/6/12.
*/
public class DatePickerDialogFragment extends BaseDialogFragment implements DatePicker.OnDateChangedListener {
public class DatePickerDialogFragment extends BaseOldDialogFragment implements DatePicker.OnDateChangedListener {
DatePicker dp_birthday;
......
......@@ -36,7 +36,7 @@ class AudioPlayer private constructor() {
private var handler: Handler? = null
private var noisyReceiver: NoisyAudioStreamReceiver? = null
private var noisyFilter: IntentFilter? = null
private var musicList: MutableList<Music> = ArrayList()
private val musicList: MutableList<Music> = ArrayList()
private val listeners = ArrayList<OnPlayerEventListener>()
private var state = STATE_IDLE
......@@ -45,7 +45,7 @@ class AudioPlayer private constructor() {
if (isPlaying) {
val current = (mediaPlayer!!.currentPosition * 1.0).toFloat()
val du = mediaPlayer!!.duration.toFloat()
var percent = (current * 100 / du).toInt()
val percent = (current * 100 / du).toInt()
//保存进度
if (autoSaveProgress) {
PlayProgressUtil.saveProgress(
......@@ -65,9 +65,9 @@ class AudioPlayer private constructor() {
val audioSessionId: Int
get() = if (mediaPlayer != null)mediaPlayer!!.audioSessionId else 0
val audioPosition: Long
val currentPosition: Long
get() = if (isPlaying || isPausing) {
mediaPlayer!!.currentPosition.toLong()
mediaPlayer!!.currentPosition
} else {
0
}
......@@ -90,6 +90,7 @@ class AudioPlayer private constructor() {
get() = state == STATE_IDLE
var playPosition: Int = 0
private set
get() {
if (field < 0 || field >= musicList.size) {
field = 0
......@@ -132,11 +133,11 @@ class AudioPlayer private constructor() {
LogUtil.e(e.message)
}
mediaPlayer!!.setOnPreparedListener { mp ->
mediaPlayer!!.setOnPreparedListener {
if (isPreparing) {
if (autoSaveProgress) {
//自动播放
var time = PlayProgressUtil.getProgress(context, playMusic!!.path)
val time = PlayProgressUtil.getProgress(context, playMusic!!.path)
if (time > 0) {
startPlayer()
seekTo(position = time.toLong())
......@@ -151,7 +152,7 @@ class AudioPlayer private constructor() {
listener.onPrepared(mediaPlayer!!.duration)
}
}
mediaPlayer!!.setOnBufferingUpdateListener { mp, percent ->
mediaPlayer!!.setOnBufferingUpdateListener { _, percent ->
for (listener in listeners) {
listener.onBufferingUpdate(percent)
}
......@@ -252,8 +253,8 @@ class AudioPlayer private constructor() {
/**
* 加载指定索引的音乐
*/
fun play(position: Int) {
var position = position
fun play(index: Int) {
var position = index
if (musicList.isEmpty()) {
return
}
......@@ -292,7 +293,7 @@ class AudioPlayer private constructor() {
* 从列表里移除播放音乐
*/
fun delete(position: Int) {
val music = musicList!!.removeAt(position)
musicList.removeAt(position)
if (playPosition > position) {
playPosition -= 1
} else if (playPosition == position) {
......@@ -312,14 +313,19 @@ class AudioPlayer private constructor() {
* 暂停或者播放音乐
*/
fun playPause() {
if (isPreparing) {
stopPlayer()
} else if (isPlaying) {
pausePlayer()
} else if (isPausing) {
startPlayer()
} else {
play(playPosition)
when {
isPreparing -> {
stopPlayer()
}
isPlaying -> {
pausePlayer()
}
isPausing -> {
startPlayer()
}
else -> {
play(playPosition)
}
}
}
......@@ -396,15 +402,13 @@ class AudioPlayer private constructor() {
if (musicList.isEmpty()) {
return
}
var playPosition = when (playMode) {
val position = when (playMode) {
PlayModeEnum.SHUFFLE -> Random().nextInt(musicList.size)
PlayModeEnum.SINGLE_LOOP -> playPosition
PlayModeEnum.LIST_LOOP -> playPosition + 1
else -> playPosition + 1
}
play(playPosition);
play(position)
}
/**
......@@ -414,12 +418,13 @@ class AudioPlayer private constructor() {
if (musicList.isEmpty()) {
return
}
when (playMode) {
PlayModeEnum.SHUFFLE -> play(Random().nextInt(musicList.size))
PlayModeEnum.SINGLE_LOOP -> play(playPosition)
PlayModeEnum.LIST_LOOP -> play(playPosition - 1)
else -> play(playPosition - 1)
val playPosition = when (playMode) {
PlayModeEnum.SHUFFLE -> Random().nextInt(musicList.size)
PlayModeEnum.SINGLE_LOOP -> playPosition
PlayModeEnum.LIST_LOOP -> playPosition - 1
else -> playPosition - 1
}
play(playPosition)
}
/**
......@@ -461,7 +466,7 @@ class AudioPlayer private constructor() {
/**
* 获取播放列表
*/
fun getMusicList(): List<Music>? {
fun getMusicList(): List<Music> {
return musicList
}
......@@ -484,4 +489,11 @@ class AudioPlayer private constructor() {
return SingletonHolder.instance
}
}
/**
* 倍速播放
*/
fun setSpeed(speed: Float) {
(mediaPlayer as? IjkMediaPlayer)?.setSpeed(speed)
}
}
......@@ -4,7 +4,7 @@ package com.ydl.media.audio.enums
* Created by haorui on 2019-10-27 .
* Des: 播放模式
*/
enum class PlayModeEnum private constructor(private val value: Int) {
enum class PlayModeEnum(private val value: Int) {
//列表循环
LIST_LOOP(0),
//随机播放
......
......@@ -68,7 +68,7 @@ class MediaSessionManager private constructor() {
mediaSession!!.setPlaybackState(
PlaybackStateCompat.Builder()
.setActions(MEDIA_SESSION_ACTIONS)
.setState(state, AudioPlayer.get().audioPosition, 1f)
.setState(state, AudioPlayer.get().currentPosition, 1f)
.build()
)
}
......
......@@ -14,10 +14,10 @@ object PlayProgressUtil {
*/
fun saveProgress(context: Context?,url : String?,progress : Int){
if (TextUtils.isEmpty(url))return
var shared = context?.getSharedPreferences("AUDIO_PLAYER_MUSIC_PROGRESS",Context.MODE_PRIVATE)
var edit = shared?.edit()
val shared = context?.getSharedPreferences("AUDIO_PLAYER_MUSIC_PROGRESS",Context.MODE_PRIVATE)
val edit = shared?.edit()
edit?.putInt(url,progress)
edit?.commit()
edit?.apply()
}
/**
......@@ -25,7 +25,7 @@ object PlayProgressUtil {
*/
fun getProgress(context: Context?,url : String?):Int{
if (TextUtils.isEmpty(url))return 0
var shared = context?.getSharedPreferences("AUDIO_PLAYER_MUSIC_PROGRESS",Context.MODE_PRIVATE)
val shared = context?.getSharedPreferences("AUDIO_PLAYER_MUSIC_PROGRESS",Context.MODE_PRIVATE)
return shared?.getInt(url,0)?:0
}
}
\ No newline at end of file
......@@ -181,7 +181,7 @@ class PlayerFloatHelper {
//FM播放页
startFMPlayActivity(context)
} else if (playingType == PlayTypeEnum.PLAY_TYPE_COURSE) {
var url = AudioPlayer.get().playMusic?.path
val url = AudioPlayer.get().playMusic?.path
//课程播放页
startCoursePlayActivity(context, 1, fullScreen, url, true)
}
......
......@@ -16,12 +16,11 @@
<ImageView
android:id="@+id/play_close"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_marginLeft="12.5dp"
android:layout_marginRight="@dimen/platform_dp_25"
android:padding="2.5dp"
android:layout_marginEnd="10dp"
android:padding="15dp"
android:src="@drawable/ico_play_float_pause"
android:visibility="visible" />
......@@ -34,7 +33,7 @@
<RelativeLayout
android:id="@+id/rl_info"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/platform_dp_18"
android:layout_marginRight="@dimen/platform_dp_18"
......@@ -55,44 +54,34 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_title"
android:maxLines="1"
android:ellipsize="end"
android:textColor="#BFBFBF"
android:textSize="10sp"
android:maxLength="10"
tools:text="丁建略丁建略丁建略丁建略" />
tools:text="丁sir" />
<TextView
android:id="@+id/tv_line"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_title"
android:layout_toRightOf="@+id/tv_name"
android:text=" | "
android:textColor="#BFBFBF"
android:textSize="10sp" />
<TextView
android:id="@+id/tv_now_playing_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_title"
android:layout_toRightOf="@+id/tv_line"
android:layout_below="@+id/tv_name"
android:textColor="#BFBFBF"
android:textSize="10sp"
tools:text="00:06" />
<TextView
android:id="@+id/tv_line_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_title"
android:layout_alignBaseline="@id/tv_now_playing_time"
android:layout_toRightOf="@+id/tv_now_playing_time"
android:text=" / "
android:textColor="#BFBFBF"
android:textSize="10sp" />
<TextView
android:layout_alignBaseline="@id/tv_now_playing_time"
android:id="@+id/tv_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
......
......@@ -4,12 +4,14 @@ import android.app.Activity
import android.content.res.Resources
import android.graphics.Color
import android.os.Bundle
import androidx.annotation.LayoutRes
import androidx.appcompat.app.AppCompatActivity
import android.os.Handler
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.annotation.LayoutRes
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.DialogFragment
import com.trello.rxlifecycle2.android.ActivityEvent
import com.ydl.ydlcommon.R
import com.ydl.ydlcommon.base.lifecycle.IActivityLifecycleable
......@@ -18,6 +20,7 @@ import com.ydl.ydlcommon.ui.LoadingDialogFragment
import com.ydl.ydlcommon.utils.ActivityManager
import com.ydl.ydlcommon.utils.AndroidSystemHelper
import com.ydl.ydlcommon.utils.StatusBarUtils
import com.ydl.ydlcommon.utils.statusBar.StatusBarUtil
import io.reactivex.subjects.BehaviorSubject
import io.reactivex.subjects.Subject
import kotlin.properties.Delegates
......@@ -42,6 +45,7 @@ abstract class BaseActivity : AppCompatActivity(), IActivityLifecycleable {
override fun onCreate(savedInstanceState: Bundle?) {
//修复Android 8.0 崩溃
AndroidSystemHelper.fixAndroidOrientationBug(this)
setImmersiveStatusBar()
super.onCreate(savedInstanceState)
Log.d("TAG", javaClass.name)
......@@ -53,6 +57,28 @@ abstract class BaseActivity : AppCompatActivity(), IActivityLifecycleable {
initDataAndEvent()
}
/**
* 开启沉浸式状态栏
* 默认关闭
*/
open fun turnOnImmersiveStatusBar() = false
/**
* true: 黑色字体
* false: 白色字体
*/
open fun setStatusBarBlackFont() = false
private fun setImmersiveStatusBar() {
if (turnOnImmersiveStatusBar()) {
StatusBarUtil.setTranslucent(window)
if (setStatusBarBlackFont())
StatusBarUtil.statusBarDarkMode(this)
else
StatusBarUtil.statusBarLightMode(this)
}
}
override fun setRequestedOrientation(requestedOrientation: Int) {
if (AndroidSystemHelper.isAllowSetOrientation(this)) {
super.setRequestedOrientation(requestedOrientation)
......@@ -60,7 +86,7 @@ abstract class BaseActivity : AppCompatActivity(), IActivityLifecycleable {
}
override fun setContentView(@LayoutRes layoutResID: Int) {
if (getStatusViewOptions()?.isAddStatusView) {
if (getStatusViewOptions().isAddStatusView) {
val options = getStatusViewOptions()
options.bottomStatusColor = getDefaultBottomColor()
val returnViews =
......@@ -183,4 +209,25 @@ abstract class BaseActivity : AppCompatActivity(), IActivityLifecycleable {
}
/**
* 展示 Fragment
* 防止崩溃异常 -> java.lang.IllegalStateException: Fragment already added
*/
fun showFragment(dialogFragment: DialogFragment?, tag: String) {
dialogFragment?.let {
val transaction = supportFragmentManager.beginTransaction()
if (it.isAdded && supportFragmentManager.findFragmentByTag(tag) != null) {
transaction.show(it)
} else {
supportFragmentManager.executePendingTransactions()
transaction.remove(dialogFragment) // 避免 Fragment already added
transaction.add(it, tag)
}
transaction.commitAllowingStateLoss()
Handler().postDelayed({
supportFragmentManager.findFragmentByTag(tag)
}, 5000)
}
}
}
\ No newline at end of file
package com.ydl.ydlcommon.base
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewDebug.ExportedProperty
import android.view.ViewDebug.IntToString
import android.view.ViewGroup
import androidx.annotation.LayoutRes
import androidx.fragment.app.DialogFragment
import com.ydl.ydlcommon.R
/**
* 弹窗基类
*/
abstract class BaseDialogFragment : DialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, R.style.bottomUpDialog)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(getLayoutResourceId(), container, false)
}
override fun onStart() {
super.onStart()
dialog?.window?.run {
attributes = attributes?.apply {
gravity = getGravity()
width = getWidth()
height = getHeight()
}
}
}
@LayoutRes
abstract fun getLayoutResourceId(): Int
open fun getGravity(): Int = Gravity.NO_GRAVITY
@ExportedProperty(
category = "layout",
mapping = [IntToString(
from = ViewGroup.LayoutParams.MATCH_PARENT,
to = "MATCH_PARENT"
), IntToString(from = ViewGroup.LayoutParams.WRAP_CONTENT, to = "WRAP_CONTENT")]
)
open fun getWidth(): Int = ViewGroup.LayoutParams.MATCH_PARENT
@ExportedProperty(
category = "layout",
mapping = [IntToString(
from = ViewGroup.LayoutParams.MATCH_PARENT,
to = "MATCH_PARENT"
), IntToString(from = ViewGroup.LayoutParams.WRAP_CONTENT, to = "WRAP_CONTENT")]
)
open fun getHeight(): Int = ViewGroup.LayoutParams.WRAP_CONTENT
}
\ No newline at end of file
......@@ -17,7 +17,7 @@ import com.ydl.ydlcommon.R;
* 基础dialog fragment
* Created by Dog on 2015/8/6.
*/
public class BaseDialogFragment extends DialogFragment {
public class BaseOldDialogFragment extends DialogFragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
......
package com.ydl.ydlcommon.utils.extend
import android.content.res.Resources
import android.text.TextUtils
inline fun <T1, T2> ifNotNull(value1: T1?, value2: T2?, bothNotNull: (t1: T1, t2: T2) -> Unit) {
if (value1 != null && value2 != null) {
bothNotNull(value1, value2)
}
}
/**
* Map 扩展
*/
fun <K, V> Map<K, V>?.getIntOr(key: K, default: Int = 0): Int {
return if (this != null) ((this[key] as? Int)?: default) else default
}
fun <K, V> Map<K, V>?.getStringOr(key: K, default: String = ""): String {
return if (this != null) ((this[key] as? String)?: default) else default
}
fun Any?.asString(default: String = ""): String {
return (this as? String) ?: default
}
inline fun String?.notEmpty(block: (String) -> Unit) {
if (this != null && this.isNotEmpty()) block(this)
}
fun String?.notEqual(other: String?): Boolean = !TextUtils.equals(this, other)
inline fun String?.notNullNotEmpty(block: (String) -> Unit) {
if (this != null && this.isNotEmpty() && this.notEqual("null")) block(this)
}
fun Number?.initZero(): Number = this ?: 0 as Number
// ---------------- ⬇️ dp px 互转 ⬇️ ------------------
val Float.dp: Float
get() = this * Resources.getSystem().displayMetrics.density
val Int.dp: Float
get() = (this * Resources.getSystem().displayMetrics.density)
// ---------------- ⬆️ dp px 互转 ️⬆️ -----------------
package com.ydl.ydlcommon.utils.extend
import android.view.View
import android.widget.TextView
import androidx.annotation.DrawableRes
fun View?.gone() {
this?.visibility = View.GONE
}
fun View?.visible() {
this?.visibility = View.VISIBLE
}
fun View?.invisible() {
this?.visibility = View.INVISIBLE
}
fun TextView?.leftDrawable(@DrawableRes left: Int) {
this?.setCompoundDrawablesWithIntrinsicBounds(left, 0, 0, 0)
}
fun TextView?.topDrawable(@DrawableRes top: Int) {
this?.setCompoundDrawablesWithIntrinsicBounds(0, top, 0, 0)
}
fun TextView?.rightDrawable(@DrawableRes right: Int) {
this?.setCompoundDrawablesWithIntrinsicBounds(0, 0, right, 0)
}
fun TextView?.bottomDrawable(@DrawableRes bottom: Int) {
this?.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, bottom)
}
fun TextView?.drawable(@DrawableRes left: Int = 0, @DrawableRes top: Int = 0, @DrawableRes right: Int = 0, @DrawableRes bottom: Int = 0) {
this?.setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom)
}
package com.ydl.ydlcommon.utils.statusBar;
import android.app.Activity;
import android.os.Build;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 魅族状态栏适配工具
*/
public class FlymeStatusbarUtils {
private static Method mSetStatusBarColorIcon;
private static Method mSetStatusBarDarkIcon;
private static Field mStatusBarColorFiled;
private static int SYSTEM_UI_FLAG_LIGHT_STATUS_BAR = 0;
static {
try {
mSetStatusBarColorIcon = Activity.class.getMethod("setStatusBarDarkIcon", int.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
try {
mSetStatusBarDarkIcon = Activity.class.getMethod("setStatusBarDarkIcon", boolean.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
try {
mStatusBarColorFiled = WindowManager.LayoutParams.class.getField("statusBarColor");
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
try {
Field field = View.class.getField("SYSTEM_UI_FLAG_LIGHT_STATUS_BAR");
SYSTEM_UI_FLAG_LIGHT_STATUS_BAR = field.getInt(null);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
/**
* 判断颜色是否偏黑色
*
* @param color 颜色
* @param level 级别
* @return
*/
public static boolean isBlackColor(int color, int level) {
int grey = toGrey(color);
return grey < level;
}
/**
* 颜色转换成灰度值
*
* @param rgb 颜色
* @return 灰度值
*/
public static int toGrey(int rgb) {
int blue = rgb & 0x000000FF;
int green = (rgb & 0x0000FF00) >> 8;
int red = (rgb & 0x00FF0000) >> 16;
return (red * 38 + green * 75 + blue * 15) >> 7;
}
/**
* 设置状态栏字体图标颜色
*
* @param activity 当前activity
* @param color 颜色
*/
public static void setStatusBarDarkIcon(Activity activity, int color) {
if (mSetStatusBarColorIcon != null) {
try {
mSetStatusBarColorIcon.invoke(activity, color);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
} else {
boolean whiteColor = isBlackColor(color, 50);
if (mStatusBarColorFiled != null) {
setStatusBarDarkIcon(activity, whiteColor, whiteColor);
setStatusBarDarkIcon(activity.getWindow(), color);
} else {
setStatusBarDarkIcon(activity, whiteColor);
}
}
}
/**
* 设置状态栏字体图标颜色(只限全屏非activity情况)
*
* @param window 当前窗口
* @param color 颜色
*/
public static void setStatusBarDarkIcon(Window window, int color) {
try {
setStatusBarColor(window, color);
if (Build.VERSION.SDK_INT > 22) {
setStatusBarDarkIcon(window.getDecorView(), true);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 设置状态栏字体图标颜色
*
* @param activity 当前activity
* @param dark 是否深色 true为深色 false 为白色
*/
public static void setStatusBarDarkIcon(Activity activity, boolean dark) {
setStatusBarDarkIcon(activity, dark, true);
}
private static boolean changeMeizuFlag(WindowManager.LayoutParams winParams, String flagName, boolean on) {
try {
Field f = winParams.getClass().getDeclaredField(flagName);
f.setAccessible(true);
int bits = f.getInt(winParams);
Field f2 = winParams.getClass().getDeclaredField("meizuFlags");
f2.setAccessible(true);
int meizuFlags = f2.getInt(winParams);
int oldFlags = meizuFlags;
if (on) {
meizuFlags |= bits;
} else {
meizuFlags &= ~bits;
}
if (oldFlags != meizuFlags) {
f2.setInt(winParams, meizuFlags);
return true;
}
} catch (Throwable e) {
e.printStackTrace();
}
return false;
}
/**
* 设置状态栏颜色
*
*/
private static void setStatusBarDarkIcon(View view, boolean dark) {
int oldVis = view.getSystemUiVisibility();
int newVis = oldVis;
if (dark) {
newVis |= SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
} else {
newVis &= ~SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
}
if (newVis != oldVis) {
view.setSystemUiVisibility(newVis);
}
}
/**
* 设置状态栏颜色
*
*/
private static void setStatusBarColor(Window window, int color) {
WindowManager.LayoutParams winParams = window.getAttributes();
if (mStatusBarColorFiled != null) {
try {
int oldColor = mStatusBarColorFiled.getInt(winParams);
if (oldColor != color) {
mStatusBarColorFiled.set(winParams, color);
window.setAttributes(winParams);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
/**
* 设置状态栏字体图标颜色(只限全屏非activity情况)
*
* @param window 当前窗口
* @param dark 是否深色 true为深色 false 为白色
*/
public static void setStatusBarDarkIcon(Window window, boolean dark) {
if (Build.VERSION.SDK_INT < 23) {
changeMeizuFlag(window.getAttributes(), "MEIZU_FLAG_DARK_STATUS_BAR_ICON", dark);
} else {
View decorView = window.getDecorView();
setStatusBarDarkIcon(decorView, dark);
setStatusBarColor(window, 0);
}
}
private static void setStatusBarDarkIcon(Activity activity, boolean dark, boolean flag) {
if (mSetStatusBarDarkIcon != null) {
try {
mSetStatusBarDarkIcon.invoke(activity, dark);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
} else {
if (flag) {
setStatusBarDarkIcon(activity.getWindow(), dark);
}
}
}
}
package com.ydl.ydlcommon.utils.statusBar;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.LinearLayout;
import androidx.core.content.ContextCompat;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* 设置状态栏
*/
public class StatusBarUtil {
private StatusBarUtil() {
}
/**
* 设置状态栏颜色
*
* @param activity 需要设置的activity
* @param color 状态栏颜色值
*/
public static void setColor(Activity activity, int color) {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// 设置状态栏透明
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// 生成一个状态栏大小的矩形
View statusView = createStatusView(activity, color);
// 添加 statusView 到布局中
ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
decorView.addView(statusView);
// 设置根布局的参数
ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
rootView.setFitsSystemWindows(true);
rootView.setClipToPadding(true);
// }
}
/**
* 生成一个和状态栏大小相同的矩形条
*
* @param activity 需要设置的activity
* @param color 状态栏颜色值
* @return 状态栏矩形条
*/
private static View createStatusView(Activity activity, int color) {
// 获得状态栏高度
int statusBarHeight = getStatusBarHeight(activity);
// 绘制一个和状态栏一样高的矩形
View statusView = new View(activity);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
statusBarHeight);
statusView.setLayoutParams(params);
statusView.setBackgroundColor(color);
return statusView;
}
public static int getStatusBarHeight(Context context) {
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
return context.getResources().getDimensionPixelSize(resourceId);
}
/**
* 修改状态栏为全透明
*/
public static void setTranslucent(Window window) {
if (null == window) return;
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
else
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
}
/**
* 修改状态栏颜色,支持4.4以上版本
*/
public static void setStatusBarColor(Activity activity, int colorId) {
Window window = activity.getWindow();
if (window == null) return;
window.setStatusBarColor(ContextCompat.getColor(activity, colorId));
}
/**
* 状态栏暗色模式,设置状态栏黑色文字、图标,
* 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android
*
* @return 1:MIUUI 2:Flyme 3:android6.0
*/
public static int statusBarDarkMode(Activity activity) {
int result = 0;
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (mIUISetStatusBarLightMode(activity.getWindow(), true)) {
result = 1;
} else if (isFlyme()) {
FlymeStatusbarUtils.setStatusBarDarkIcon(activity, true);
result = 2;
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
setAndroidNativeLightStatusBar(activity.getWindow(), true);
result = 3;
}
// }
return result;
}
/**
* 状态栏亮色模式,设置状态栏白色文字、图标,
* 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android
*
* @return 1:MIUUI 2:Flyme 3:android6.0w
*/
public static int statusBarLightMode(Activity activity) {
int result = 0;
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (mIUISetStatusBarLightMode(activity.getWindow(), false)) {
result = 1;
} else if (isFlyme()) {
FlymeStatusbarUtils.setStatusBarDarkIcon(activity, false);
result = 2;
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
setAndroidNativeLightStatusBar(activity.getWindow(), false);
result = 3;
}
// }
return result;
}
/**
* 判断是否为魅族手机
*/
private static boolean isFlyme() {
return "Meizu".equalsIgnoreCase(Build.BRAND);
}
/**
* 状态栏暗色模式,清除MIUI、flyme或6.0以上版本状态栏黑色文字、图标
*/
public static void statusBarDarkMode(Activity activity, int type) {
if (type == 1) {
mIUISetStatusBarLightMode(activity.getWindow(), true);
} else if (type == 2) {
FlymeStatusbarUtils.setStatusBarDarkIcon(activity, true);
} else if (type == 3) {
setAndroidNativeLightStatusBar(activity.getWindow(), true);
}
}
/**
* 状态栏亮色模式,清除MIUI、flyme或6.0以上版本状态栏黑色文字、图标
*/
public static void statusBarLightMode(Activity activity, int type) {
if (type == 1) {
mIUISetStatusBarLightMode(activity.getWindow(), false);
} else if (type == 2) {
FlymeStatusbarUtils.setStatusBarDarkIcon(activity, false);
} else if (type == 3) {
setAndroidNativeLightStatusBar(activity.getWindow(), false);
}
}
/**
* 需要MIUIV6以上
*
* @param dark 是否把状态栏文字及图标颜色设置为深色
* @return boolean 成功执行返回true
*/
private static boolean mIUISetStatusBarLightMode(Window window, boolean dark) {
boolean result = false;
if (window != null) {
Class<?> clazz = window.getClass();
try {
int darkModeFlag;
Class<?> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
darkModeFlag = field.getInt(layoutParams);
Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
if (dark) {
extraFlagField.invoke(window, darkModeFlag, darkModeFlag);//状态栏透明且黑色字体
} else {
extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字体
}
result = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//开发版 7.7.13 及以后版本采用了系统API,旧方法无效但不会报错,所以两个方式都要加上
if (dark) {
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else {
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
return result;
}
private static void setAndroidNativeLightStatusBar(Window window, boolean dark) {
View decor = window.getDecorView();
if (dark) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
else
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
} else {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="@android:integer/config_mediumAnimTime"
android:interpolator="@android:anim/accelerate_interpolator"
android:duration="@android:integer/config_longAnimTime"
android:fromYDelta="0"
android:toYDelta="100%p"/>
</set>
\ No newline at end of file
......@@ -2,8 +2,7 @@
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="@android:integer/config_mediumAnimTime"
android:interpolator="@android:anim/accelerate_interpolator"
android:duration="@android:integer/config_longAnimTime"
android:fromYDelta="100%p"
android:toYDelta="0"/>
</set>
\ No newline at end of file
......@@ -122,5 +122,13 @@
<!--次级按钮字体颜色,和背景冲突时使用,黑色基本不变-->
<color name="platform_but_text_color_specific">#222222</color>
<color name="color_FAFAFB">#FAFAFB</color>
<color name="color_1C1F28">#1C1F28</color>
<color name="color_1DA1F2">#1DA1F2</color>
<color name="color_EB892C">#EB892C</color>
<color name="color_9D9EA7">#9D9EA7</color>
<color name="color_EFEFF1">#EFEFF1</color>
<color name="color_FAFAFF">#FAFAFF</color>
</resources>
......@@ -55,7 +55,7 @@
<item name="android:layout_height">0.5dp</item>
</style>
<style name="platform_BottomDialogAnimation">
<style name="platform_BottomDialogAnimation" parent="baseDialog">
<item name="android:windowEnterAnimation">@anim/platform_bottom_dialog_slide_show</item>
<item name="android:windowExitAnimation">@anim/platform_bottom_dialog_slide_hide</item>
</style>
......@@ -70,5 +70,19 @@
<item name="colorAccent">@color/platform_main_theme</item>
</style>
<style name="baseDialog" parent="android:style/Theme.Dialog">
<item name="android:windowNoTitle">true</item><!-- 是否显示title -->
<item name="android:windowFrame">@null</item><!-- Dialog的windowFrame框 -->
<item name="android:windowIsFloating">true</item><!-- 是否浮现在activity之上 -->
<item name="android:windowBackground">@android:color/transparent</item><!--背景透明-->
<item name="android:background">@android:color/transparent</item>
<item name="android:backgroundDimEnabled">true</item>
<!-- 用来控制灰度的值,当为1时,界面除了我们的dialog内容是高亮显示的,dialog以外的区域是黑色的,完全看不到其他内容,系统的默认值是0.5 -->
<item name="android:backgroundDimAmount">0.6</item>
<item name="android:windowMinWidthMajor">50%</item>
<item name="android:windowMinWidthMinor">50%</item>
</style>
<style name="bottomUpDialog" parent="baseDialog">
<item name="android:windowAnimationStyle">@style/platform_BottomDialogAnimation</item>
</style>
</resources>
\ 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