| | |
| | | import cn.sinata.xldutils.fragment.BaseFragment |
| | | import cn.sinata.xldutils.gone |
| | | import cn.sinata.xldutils.visible |
| | | import com.danikula.videocache.CacheListener |
| | | import com.github.penfeizhou.animation.apng.APNGDrawable |
| | | import com.google.android.material.bottomsheet.BottomSheetBehavior |
| | | import com.luck.picture.lib.tools.SPUtils |
| | | import com.sinata.xqmuse.MainActivity |
| | | import com.sinata.xqmuse.R |
| | | import com.sinata.xqmuse.dialog.TreeTipDialog |
| | |
| | | import com.sinata.xqmuse.utils.AudioUtils |
| | | import com.sinata.xqmuse.utils.Const |
| | | import com.sinata.xqmuse.utils.ScreenUtil |
| | | import com.sinata.xqmuse.utils.cache.ProxyVideoCacheManager |
| | | import com.sinata.xqmuse.utils.event.EmptyEvent |
| | | import com.sinata.xqmuse.utils.extention.checkLogin |
| | | import com.sinata.xqmuse.utils.extention.clickDelay |
| | | import com.sinata.xqmuse.utils.interfaces.StringCallback |
| | | import kotlinx.android.synthetic.main.fragment_tree.* |
| | | import okhttp3.* |
| | | import org.greenrobot.eventbus.EventBus |
| | | import org.jetbrains.anko.support.v4.dip |
| | | import org.jetbrains.anko.support.v4.runOnUiThread |
| | | import org.jetbrains.anko.support.v4.startActivity |
| | | import org.jetbrains.anko.support.v4.toast |
| | | import retrofit2.Retrofit |
| | | import java.io.File |
| | | import java.io.FileOutputStream |
| | | import java.io.IOException |
| | | import java.io.InputStream |
| | | import java.net.HttpURLConnection |
| | | import java.net.URL |
| | | import kotlin.math.max |
| | | |
| | | |
| | | class TreeFragment : BaseFragment() { |
| | | override fun contentViewId() = R.layout.fragment_tree |
| | |
| | | |
| | | private val audioPlayer by lazy { AudioUtils() } //音频播放 |
| | | private var tree:TreeInfo? = null |
| | | private val cacheDir by lazy { requireActivity().cacheDir } |
| | | //常量 |
| | | val GROWTH_ANIM_DURATION = 500L |
| | | |
| | |
| | | tv_rule.setOnClickListener { |
| | | HttpManager.getH5(6).requestByF(this){ _, data-> |
| | | data?.let { |
| | | startActivity<H5Activity>("title" to "规则说明","url" to it.content,"showClose" to false) |
| | | startActivity<H5Activity>( |
| | | "title" to "规则说明", |
| | | "url" to it.content, |
| | | "showClose" to false |
| | | ) |
| | | } |
| | | } |
| | | } |
| | | |
| | | tv_sign.clickDelay { |
| | | HttpManager.sign().requestByF(this){_,data-> |
| | | HttpManager.sign().requestByF(this){ _, data-> |
| | | tv_sign.isEnabled = false |
| | | tv_sign.text = "已签到" |
| | | tree?.energyValue = (tree?.energyValue?:0)+10 |
| | | tree?.totalEnergyValue = (tree?.totalEnergyValue?:0)+10 |
| | | tv_power.text = "当前能量值:${(tree?.energyValue?:0)}" |
| | | signed.visible() |
| | | signed.postDelayed({signed.gone()},1500) |
| | | signed.postDelayed({ signed.gone() }, 1500) |
| | | } |
| | | } |
| | | tv_to_think.setOnClickListener { |
| | |
| | | EventBus.getDefault().post(EmptyEvent(Const.EventCode.SWITCH_HOME)) |
| | | } |
| | | iv_water.clickDelay { |
| | | showWater() |
| | | // showWater() |
| | | // return@clickDelay |
| | | // tree?.energyValue = 0 |
| | | // tree!!.treeLevelType++ |
| | | // showTreeAnim(tree!!.getTreeApng(),true) |
| | |
| | | else if (tree?.sowAgain == 1) |
| | | toast("树苗已成熟,请重新播种") |
| | | else |
| | | HttpManager.watering().requestByF(this){_,data-> |
| | | HttpManager.watering().requestByF(this){ _, data-> |
| | | data?.apply { |
| | | EventBus.getDefault().post(EmptyEvent(Const.EventCode.USER_INFO_CHANGED)) //刷新成长值 |
| | | tv_max.text = "/$nextLevel" |
| | | tv_growth.text = growthValue.toString() |
| | | val targetHeight = growthValue.toDouble()/nextLevel*dip(155) |
| | | val layoutParams = progress.layoutParams |
| | | showGrowthAnim(layoutParams.height, max(1,targetHeight.toInt())) |
| | | showGrowthAnim(layoutParams.height, max(1, targetHeight.toInt())) |
| | | showWater() |
| | | tree?.energyValue = energyValue |
| | | tv_power.text = "当前能量值:${(tree?.energyValue?:0)}" |
| | |
| | | showGrowUpDialog(data.treeLevelType) |
| | | }else if (tree!!.status != 2){ |
| | | tree!!.status = 2 |
| | | showTreeAnim(tree!!.getTreeApng(),tree!!.treeLevelType != 1) |
| | | showTreeAnim(tree!!.getTreeApng(), tree!!.treeLevelType != 1) |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | tv_again.setOnClickListener { |
| | | HttpManager.restart().requestByF(this){_,_-> |
| | | HttpManager.restart().requestByF(this){ _, _-> |
| | | getTree() |
| | | } |
| | | } |
| | |
| | | |
| | | private fun checkFirst() { |
| | | if (checkLogin()) |
| | | HttpManager.isFirst().requestByF(this){_,data-> |
| | | HttpManager.isFirst().requestByF(this){ _, data-> |
| | | if (data == true) |
| | | showFirst() |
| | | } |
| | |
| | | /** |
| | | * 依次弹窗升级和播放语音 |
| | | */ |
| | | private fun showGrowUpDialog(targetLevel:Int){ |
| | | private fun showGrowUpDialog(targetLevel: Int){ |
| | | tree!!.treeLevelType++ |
| | | showTreeAnim(tree!!.getTreeApng(),true) |
| | | audioPlayer.startPlayMusic(requireContext(),tree!!.getLevelUpAudio()) |
| | | val dialog = TreeTipDialog.show(childFragmentManager,"生命之树",tree!!.getLevelName()) |
| | | audioPlayer.setOnAudioStatusUpdateListener(object :AudioUtils.OnAudioStatusUpdateListener{ |
| | | showTreeAnim(tree!!.getTreeApng(), true) |
| | | audioPlayer.startPlayMusic(requireContext(), tree!!.getLevelUpAudio()) |
| | | val dialog = TreeTipDialog.show(childFragmentManager, "生命之树", tree!!.getLevelName()) |
| | | audioPlayer.setOnAudioStatusUpdateListener(object : AudioUtils.OnAudioStatusUpdateListener { |
| | | override fun onUpdate(db: Double, time: Long) { |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | fun getTree(){ |
| | | HttpManager.getUserTree().requestByF(this){_,data-> |
| | | HttpManager.getUserTree().requestByF(this){ _, data-> |
| | | val changed = data?.treeLevelType != tree?.treeLevelType //等级发生变化 |
| | | tree = data |
| | | data?.apply { |
| | |
| | | tv_growth.text = growthValue.toString() |
| | | val targetHeight = growthValue.toDouble()/nextLevel*dip(155) |
| | | val layoutParams = progress.layoutParams |
| | | showGrowthAnim(layoutParams.height, max(1,targetHeight.toInt())) |
| | | showGrowthAnim(layoutParams.height, max(1, targetHeight.toInt())) |
| | | tv_sign.isEnabled = isSign == 2 |
| | | tv_sign.text = if (tv_sign.isEnabled) "打卡签到" else "已签到" |
| | | tv_to_think.isEnabled = taskOne == 2 |
| | | tv_to_think_2.isEnabled = taskTwo == 2 |
| | | if (status == 2){ |
| | | if (changed) |
| | | showTreeAnim(getTreeApng(),treeLevelType != 1) |
| | | showTreeAnim(getTreeApng(), treeLevelType != 1) |
| | | } else |
| | | showTreeDead() |
| | | } |
| | |
| | | fun showFirst(){ |
| | | if (!(activity as MainActivity).hasTreeFirstShow){ |
| | | TreeTipDialog.show(childFragmentManager) |
| | | audioPlayer.startPlayMusic(requireContext(),Const.TREE.first) |
| | | audioPlayer.startPlayMusic(requireContext(), Const.VOICE_TREE.first) |
| | | } |
| | | } |
| | | |
| | |
| | | /** |
| | | * 成长值动画 |
| | | */ |
| | | private fun showGrowthAnim(start:Int,end:Int){ |
| | | private fun showGrowthAnim(start: Int, end: Int){ |
| | | val ofInt = ValueAnimator.ofInt(start, end) |
| | | ofInt.duration = GROWTH_ANIM_DURATION |
| | | ofInt.addUpdateListener { |
| | |
| | | } |
| | | |
| | | private fun showWater(){ |
| | | val apngDrawable = APNGDrawable.fromAsset(requireContext(),"apngb_water.png") |
| | | iv_water_anim.setImageDrawable(apngDrawable) |
| | | apngDrawable.setLoopLimit(2) |
| | | apngDrawable.registerAnimationCallback(object :Animatable2Compat.AnimationCallback(){ |
| | | override fun onAnimationEnd(drawable: Drawable?) { |
| | | super.onAnimationEnd(drawable) |
| | | iv_water_anim.setImageResource(0) |
| | | // val apngDrawable = APNGDrawable.fromAsset(requireContext(),"apngb_water.png") |
| | | // iv_water_anim.setImageDrawable(apngDrawable) |
| | | // apngDrawable.setLoopLimit(2) |
| | | // apngDrawable.registerAnimationCallback(object : Animatable2Compat.AnimationCallback(){ |
| | | // override fun onAnimationEnd(drawable: Drawable?) { |
| | | // super.onAnimationEnd(drawable) |
| | | // iv_water_anim.setImageResource(0) |
| | | // } |
| | | // }) |
| | | showOrDownApng(Const.APNG_TREE.WATER,object :StringCallback{ |
| | | override fun onResult(rst: String) { |
| | | waterAnim() |
| | | } |
| | | }) |
| | | } |
| | | |
| | | private fun showOrDownApng(url:String,callback: StringCallback){ |
| | | if (isFileCached(url)){ |
| | | callback.onResult("") |
| | | }else |
| | | downloadFileToCache(url,callback) |
| | | } |
| | | |
| | | private fun waterAnim(){ |
| | | val apngDrawable = APNGDrawable.fromFile(getCachedFile(Const.APNG_TREE.WATER)?.absolutePath) |
| | | runOnUiThread { |
| | | iv_water_anim.setImageDrawable(apngDrawable) |
| | | apngDrawable.setLoopLimit(2) |
| | | apngDrawable.registerAnimationCallback(object : Animatable2Compat.AnimationCallback(){ |
| | | override fun onAnimationEnd(drawable: Drawable?) { |
| | | super.onAnimationEnd(drawable) |
| | | iv_water_anim.setImageResource(0) |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | // 获取缓存文件路径 |
| | | fun getCachedFile(url: String): File? { |
| | | val cacheDir = requireActivity().cacheDir |
| | | val file = File(cacheDir, url.substring(url.lastIndexOf("/"))) |
| | | return if (file.exists()) file else null |
| | | } |
| | | |
| | | // 检查文件是否已缓存 |
| | | fun isFileCached(url: String): Boolean { |
| | | return getCachedFile(url) != null |
| | | } |
| | | |
| | | fun downloadFileToCache(url: String,callback: StringCallback) { |
| | | val client = OkHttpClient() |
| | | val request = Request.Builder().url(url).build() |
| | | |
| | | client.newCall(request).enqueue(object : okhttp3.Callback { |
| | | override fun onFailure(call: okhttp3.Call, e: IOException) { |
| | | // 下载失败处理 |
| | | e.printStackTrace() |
| | | } |
| | | |
| | | override fun onResponse(call: Call, response: Response) { |
| | | if (!response.isSuccessful) { |
| | | throw IOException("下载失败: ${response.code()}") |
| | | } |
| | | |
| | | // 获取内部缓存目录 |
| | | val cacheDir = requireActivity().cacheDir |
| | | val outputFile = File(cacheDir, url.substring(url.lastIndexOf("/") + 1)) |
| | | if (outputFile.exists() && outputFile.isDirectory) { |
| | | // 删除目录或调整文件名 |
| | | outputFile.delete() |
| | | } |
| | | try { |
| | | // 将文件写入缓存 |
| | | val inputStream = response.body()?.byteStream() |
| | | val outputStream = FileOutputStream(outputFile) |
| | | inputStream?.use { input -> |
| | | outputStream.use { output -> |
| | | input.copyTo(output) |
| | | } |
| | | } |
| | | // 下载成功,文件路径为 outputFile.absolutePath |
| | | callback.onResult("") |
| | | } catch (e: Exception) { |
| | | e.printStackTrace() |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | private fun showSunshine(){ |
| | | val apngDrawable = APNGDrawable.fromAsset(requireContext(),"sunshine.png") |
| | | iv_sunshine.setImageDrawable(apngDrawable) |
| | | showOrDownApng(Const.APNG_TREE.SUNSHINE,object :StringCallback{ |
| | | override fun onResult(rst: String) { |
| | | runOnUiThread { |
| | | val apngDrawable = APNGDrawable.fromFile(getCachedFile(Const.APNG_TREE.SUNSHINE)?.absolutePath) |
| | | iv_sunshine.setImageDrawable(apngDrawable) |
| | | } |
| | | } |
| | | }) |
| | | // val apngDrawable = APNGDrawable.fromAsset(requireContext(), "sunshine.png") |
| | | // iv_sunshine.setImageDrawable(apngDrawable) |
| | | // apngDrawable.setLoopLimit(5) |
| | | } |
| | | |
| | | private fun showTreeAnim(resStr:String,isLoop:Boolean){ |
| | | val apngDrawable = APNGDrawable.fromAsset(requireContext(),resStr) |
| | | iv_tree.setImageDrawable(apngDrawable) |
| | | apngDrawable.setLoopLimit(if (isLoop) -1 else 1) |
| | | if (tree?.treeLevelType?:0 >= 10) |
| | | tv_again.visible() |
| | | else |
| | | tv_again.gone() |
| | | private fun showTreeAnim(resStr: String, isLoop: Boolean){ |
| | | showOrDownApng(resStr,object :StringCallback{ |
| | | override fun onResult(rst: String) { |
| | | runOnUiThread { |
| | | val apngDrawable = APNGDrawable.fromFile(getCachedFile(resStr)?.absolutePath) |
| | | iv_tree.setImageDrawable(apngDrawable) |
| | | apngDrawable.setLoopLimit(if (isLoop) -1 else 1) |
| | | if (tree?.treeLevelType?:0 >= 10) |
| | | tv_again.visible() |
| | | else |
| | | tv_again.gone() |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | override fun onPause() { |