Commit 4e2e7482 authored by jyx's avatar jyx

添加激励视频,添加推荐页面布局

parent c14e01ff
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_15" default="true" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
......
......@@ -63,6 +63,7 @@ android {
buildConfigField "String", "MainIp", DEBUG_URL
buildConfigField "String", "GROMORE_APP_ID", GROMORE_APP_ID
buildConfigField "String", "GROMORE_SPLASH_CODE", GROMORE_SPLASH_CODE
buildConfigField "String", "GROMORE_VIDEO_CODE", GROMORE_VIDEO_CODE
buildConfigField "String", "WEIXIN_APP_PAY_ID", WEIXIN_APP_PAY_ID
//混淆
......@@ -81,6 +82,7 @@ android {
buildConfigField "String", "MainIp", RELEASE_URL
buildConfigField "String", "GROMORE_APP_ID", GROMORE_APP_ID
buildConfigField "String", "GROMORE_SPLASH_CODE", GROMORE_SPLASH_CODE
buildConfigField "String", "GROMORE_VIDEO_CODE", GROMORE_VIDEO_CODE
buildConfigField "String", "WEIXIN_APP_PAY_ID", WEIXIN_APP_PAY_ID
//混淆
......
......@@ -58,11 +58,7 @@
android:configChanges="orientation|screenSize|keyboardHidden"
android:exported="true"
android:theme="@style/AppTheme.TranslucentSplish">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.activitys.SplashAdActivity"
......@@ -78,10 +74,16 @@
<activity
android:name=".ui.activitys.MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:exported="false"
android:exported="true"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoneTranslucent" />
android:theme="@style/AppTheme.NoneTranslucent">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.activitys.WebActivity"
android:exported="false"
......
package com.mints.wisdomclean.ad
import android.app.Activity
import com.mints.wisdomclean.ad.video.InMoneyVideo
/**
* 预加载-全屏及激励视频管理类
*/
class AdManager {
private val TAG = AdManager::class.java.simpleName
companion object {
const val AD_NO_SHOWTIME_OUT = 50 // 广告请示成功但在规定时间内未展示
const val AD_REQUEST_TIME_OUT = 1 // 广告预加载时长超时
val instance: AdManager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
AdManager()
}
}
/**
* 根据服务器概率预加载广告
*
* isPreLoad:是否是预加载调用,需要躲避监听
*/
fun preLoadAd(activity: Activity, isPreLoad: Boolean = false) {
// 加载激励视频广告
this.loadRewardVideo(activity, isPreLoad)
}
/**
* 根据预加载类型 展示广告
*/
fun showAd(
activity: Activity,
carrierType: String,
AdStatusListener: AdStatusListener?,
) {
// 加载激励视频广告
showRewardVideo(activity, AdStatusListener, carrierType)
}
// 预加载激励视频广告
private fun loadRewardVideo(activity: Activity, isPreLoad: Boolean = false) {
InMoneyVideo.getInstance().preLoadAd(activity, isPreLoad)
}
// 展示激励视频广告
private fun showRewardVideo(
activity: Activity,
AdStatusListener: AdStatusListener?,
carrierType: String,
) {
InMoneyVideo.getInstance()
.showRewardAd(
activity,
AdStatusListener,
carrierType,
)
}
/**
* 开屏页使用-预加载广告
*/
fun splashPreLoadAll(activity: Activity) {
this.loadRewardVideo(activity)
}
}
\ No newline at end of file
package com.mints.wisdomclean.ad
/**
* 广告状态触发事件
*/
abstract class AdNoProListener : IAdNoProListener {
}
interface IAdNoProListener {
fun adFail()
fun adSuccess()
fun adClose()
}
\ No newline at end of file
package com.mints.wisdomclean.ad
import android.app.Activity
import com.mints.wisdomclean.ad.video.InMoneyVideoNoPre
/**
* 实时加载激励视频、全屏
*/
object NoPreAdManager {
private val TAG = NoPreAdManager::class.java.simpleName
fun loadVideoAd(
activity: Activity,
carrierType: String,
listener: AdNoProListener?
) {
val adNoProListener = object : AdNoProListener() {
override fun adFail() {
listener?.adFail()
}
override fun adSuccess() {
listener?.adSuccess()
}
override fun adClose() {
listener?.adClose()
}
}
InMoneyVideoNoPre.getInstance().loadAd(activity, adNoProListener, carrierType)
}
}
\ No newline at end of file
package com.mints.wisdomclean.ad.video;
import android.app.Activity;
import com.bytedance.msdk.api.AdError;
import com.bytedance.msdk.api.reward.RewardItem;
import com.bytedance.msdk.api.v2.GMAdConstant;
import com.bytedance.msdk.api.v2.GMMediationAdSdk;
import com.bytedance.msdk.api.v2.GMSettingConfigCallback;
import com.bytedance.msdk.api.v2.ad.reward.GMRewardAd;
import com.bytedance.msdk.api.v2.ad.reward.GMRewardedAdListener;
import com.bytedance.msdk.api.v2.ad.reward.GMRewardedAdLoadCallback;
import com.bytedance.msdk.api.v2.slot.GMAdOptionUtil;
import com.bytedance.msdk.api.v2.slot.GMAdSlotRewardVideo;
import com.mints.library.utils.json.JsonUtil;
import com.mints.wisdomclean.BuildConfig;
import com.mints.wisdomclean.ad.AdNoProListener;
import com.mints.wisdomclean.common.Constant;
import com.mints.wisdomclean.manager.TrackManager;
import com.mints.wisdomclean.manager.UserManager;
import com.mints.wisdomclean.utils.LogUtil;
import java.lang.ref.WeakReference;
import java.util.HashMap;
/**
* **实时加载
* <p>
* 应用内-GroMore激励视频广告
*/
public class InMoneyVideoNoPre {
private static final String TAG = InMoneyVideoNoPre.class.getSimpleName();
private static InMoneyVideoNoPre _inst;
public static InMoneyVideoNoPre getInstance() {
if (_inst == null) {
_inst = new InMoneyVideoNoPre();
}
return _inst;
}
private InMoneyVideoNoPre() {
}
private String carrierType = "";
// 当前播放的广告
private String nowAdcode = "";
private String nowEcpm = "";
private String nowAdSource = "";
private GMRewardAd mttRewardAd;
private WeakReference<Activity> weakActivity;
private boolean isClickScreen = true; // 是否点击屏幕跳转广告
private AdNoProListener adNoProListener;
/**
* 激励视频
*/
public void loadAd(Activity _activity, AdNoProListener adNoProListener, String carrier) {
this.carrierType = carrier;
this.adNoProListener = adNoProListener;
this.weakActivity = new WeakReference(_activity);
this.isClickScreen = true;
/*
* 判断当前是否存在config 配置 ,如果存在直接加载广告 ,如果不存在则注册config加载回调
*/
if (GMMediationAdSdk.configLoadSuccess()) {
preLoadAd(BuildConfig.GROMORE_VIDEO_CODE, GMAdConstant.VERTICAL);
} else {
GMMediationAdSdk.registerConfigCallback(mSettingConfigCallback); //不用使用内部类,否则在ondestory中无法移除该回调
}
}
private void preLoadAd(final String adUnitId, int orientation) {
/*
* 注:每次加载激励视频广告的时候需要新建一个TTRewardAd,否则可能会出现广告填充问题
* ( 例如:mttRewardAd = new TTRewardAd(this, adUnitId);)
*/
mttRewardAd = new GMRewardAd(this.weakActivity.get(), adUnitId);
GMAdSlotRewardVideo adSlotRewardVideo = new GMAdSlotRewardVideo.Builder()
.setMuted(true)//对所有SDK的激励广告生效,除需要在平台配置的SDK,如穿山甲SDK
.setVolume(0f)//配合Admob的声音大小设置[0-1]
.setGMAdSlotGDTOption(GMAdOptionUtil.getGMAdSlotGDTOption().build())
.setGMAdSlotBaiduOption(GMAdOptionUtil.getGMAdSlotBaiduOption().build())
.setRewardName("金币") //奖励的名称
.setRewardAmount(0) //奖励的数量
.setUserID(UserManager.getInstance().getUserID())//用户id,必传参数
.setUseSurfaceView(false)
.setOrientation(orientation)//必填参数,期望视频的播放方向:GMAdConstant.HORIZONTAL 或 GMAdConstant.VERTICAL
.build();
//请求广告
mttRewardAd.loadAd(adSlotRewardVideo, new GMRewardedAdLoadCallback() {
@Override
public void onRewardVideoLoadFail(AdError adError) {
LogUtil.e(TAG, "InMoneyVideoNoPre应用内激励视频广告-->onError " + adError.code + adError.message + " id=" + adUnitId);
LogUtil.e(TAG, "InMoneyVideoNoPre应用内激励视频广告-->onRewardVideoLoadFail result=" + JsonUtil.toJson(mttRewardAd.getAdLoadInfoList()));
if (adNoProListener != null) {
adNoProListener.adFail();
}
}
@Override
public void onRewardVideoAdLoad() {
}
@Override
public void onRewardVideoCached() {
LogUtil.d(TAG, "InMoneyVideoNoPre应用内激励视频广告--> 4、onRewardVideoCached id=" + adUnitId);
if (mttRewardAd != null && weakActivity != null) {
mttRewardAd.setRewardAdListener(mTTRewardedAdListener);
mttRewardAd.showRewardAd(weakActivity.get());
} else {
LogUtil.e(TAG, " onRewardVideoCached onError ");
if (adNoProListener != null) {
adNoProListener.adFail();
}
}
}
});
}
/**
* config回调
*/
private final GMSettingConfigCallback mSettingConfigCallback = () -> preLoadAd(BuildConfig.GROMORE_VIDEO_CODE, GMAdConstant.VERTICAL);
/**
* 激励视频交互回调
*/
private final GMRewardedAdListener mTTRewardedAdListener = new GMRewardedAdListener() {
/**
* 广告的展示回调 每个广告仅回调一次
*/
public void onRewardedAdShow() {
if (adNoProListener != null) {
adNoProListener.adSuccess();
}
if (mttRewardAd != null) {
if (mttRewardAd.getShowEcpm() != null) {
nowAdcode = mttRewardAd.getShowEcpm().getAdNetworkRitId();
nowEcpm = mttRewardAd.getShowEcpm().getPreEcpm();
nowAdSource = mttRewardAd.getShowEcpm().getAdNetworkPlatformName();
}
HashMap<String, Object> vo = new HashMap<>();
vo.put("adcode", nowAdcode);
vo.put("ecpm", nowEcpm);
vo.put("adSource", nowAdSource);
vo.put("carrierType", carrierType);
vo.put("adType", Constant.GRO_MORE_ADTYPE2);
vo.put("adid", BuildConfig.GROMORE_VIDEO_CODE);
vo.put("isAddCoin", true);
TrackManager.getInstance().cmtGroMoreInfo(vo);
TrackManager.getInstance().reporGromeEcpm(vo);
}
LogUtil.d(TAG, "InMoneyVideoNoPre应用内激励视频广告-->onRewardedAdShow");
// 预加载
// if (weakActivity.get() != null) {
// LogUtil.d(TAG, "InMoneyVideoNoPre应用内激励视频广告->onFullVideoAdShow 触发预加载下次广告");
// AdManager.Companion.getInstance().preLoadAd(weakActivity.get(),true);
// }
}
@Override
public void onRewardedAdShowFail(AdError adError) {
LogUtil.e(TAG, "InMoneyVideoNoPre应用内激励视频广告-->onRewardedAdShowFail msg=" + adError.message);
}
/**
* 注意Admob的激励视频不会回调该方法
*/
@Override
public void onRewardClick() {
LogUtil.d(TAG, "InMoneyVideoNoPre应用内激励视频广告-->onRewardClick");
if (isClickScreen) {
// 防止重复
isClickScreen = false;
}
}
/**
* 广告关闭的回调
*/
public void onRewardedAdClosed() {
LogUtil.d(TAG, "InMoneyVideoNoPre应用内激励视频广告-->onRewardedAdClosed nowAdcode=" + nowAdcode);
if (adNoProListener != null) {
adNoProListener.adClose();
}
adNoProListener = null;
}
/**
* 视频播放完毕的回调 Admob广告不存在该回调
*/
public void onVideoComplete() {
LogUtil.d(TAG, "onVideoComplete");
}
/**
* 视频播放失败的回调 - Mintegral GDT Admob广告不存在该回调
*/
public void onVideoError() {
LogUtil.e(TAG, "InMoneyVideoNoPre应用内激励视频广告-->onVideoError");
if (adNoProListener != null) {
adNoProListener.adFail();
}
}
/**
* 激励视频播放完毕,验证是否有效发放奖励的回调
*/
public void onRewardVerify(RewardItem rewardItem) {
// Map<String, Object> customData = rewardItem.getCustomData();
// if (customData != null) {
// String adnName = (String) customData.get(RewardItem.KEY_ADN_NAME);
// if (RewardItem.KEY_GDT.equals(adnName)) {
// LogUtil.d(TAG, "rewardItem gdt: " + customData.get(RewardItem.KEY_GDT_TRANS_ID));
// }
// }
}
/**
* - Mintegral GDT Admob广告不存在该回调
*/
@Override
public void onSkippedVideo() {
}
};
}
......@@ -2,6 +2,10 @@ package com.mints.wisdomclean.common
object Constant {
const val GRO_MORE_ADTYPE2 = "2"
const val AD_SOURCE_GROMORE = "GROMORE"
/**
* 首次弹出权限声明
*/
......
package com.mints.wisdomclean.manager;
import android.text.TextUtils;
import com.mints.wisdomclean.MintsApplication;
import com.mints.wisdomclean.mvp.presenters.TrackPresenter;
import java.util.HashMap;
/**
* 描述:离线管理器
*/
......@@ -39,4 +43,17 @@ public class TrackManager {
}
}
public void cmtGroMoreInfo(HashMap<String, Object> vo) {
if (trackPresenter != null && !TextUtils.isEmpty(UserManager.getInstance().getUserID())) {
trackPresenter.cmtGroMoreInfo(vo);
}
}
public void reporGromeEcpm(HashMap<String, Object> vo) {
if (trackPresenter != null && !TextUtils.isEmpty(UserManager.getInstance().getUserID())) {
trackPresenter.reporGromeEcpm(vo);
}
}
}
package com.mints.wisdomclean.mvp.presenters;
import com.google.gson.JsonObject;
import com.mints.library.net.neterror.BaseSubscriber;
import com.mints.library.net.neterror.Throwable;
import com.mints.wisdomclean.MintsApplication;
import com.mints.wisdomclean.common.AppConfig;
import com.mints.wisdomclean.common.DeviceInfo;
import com.mints.wisdomclean.manager.AppHttpManager;
import com.mints.wisdomclean.manager.UserManager;
......@@ -72,4 +74,43 @@ public class TrackPresenter extends BaseTrackPresenter {
});
}
public void cmtGroMoreInfo(HashMap<String, Object> vo) {
AppHttpManager.getInstance(loanApplication)
.call(loanService.reportAdIncome(vo),
new BaseSubscriber<BaseResponse<Object>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(BaseResponse<Object> baseResponse) {
}
});
}
public void reporGromeEcpm(HashMap<String, Object> vo) {
AppHttpManager.getInstance(loanApplication)
.call(loanService.reporGromeEcpm(vo),
new BaseSubscriber<BaseResponse<JsonObject>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(BaseResponse<JsonObject> baseResponse) {
}
});
}
}
......@@ -141,6 +141,23 @@ public interface LoanService {
@POST("api/vip/unSign")
Observable<BaseResponse<JsonObject>> unSign();
/**
* groMore数据提交
*
* @return
*/
@POST("api/reportAdIncome")
Observable<BaseResponse<Object>> reportAdIncome(@Body Map<String, Object> vo);
/**
* groMore激励视频展示广告提交数据
*
* @return
*/
@POST("api/reporGromeEcpm")
Observable<BaseResponse<JsonObject>> reporGromeEcpm(@Body Map<String, Object> vo);
/**
* 默认http工厂
*/
......
......@@ -23,6 +23,7 @@ import com.mints.wisdomclean.common.Constant
import com.mints.wisdomclean.ui.activitys.base.BaseActivity
import com.mints.wisdomclean.ui.fragment.MainFragment
import com.mints.wisdomclean.ui.fragment.MyFragment
import com.mints.wisdomclean.ui.fragment.RecommendFragment
import com.mints.wisdomclean.ui.widgets.DialogListener
import com.mints.wisdomclean.ui.widgets.PhoneDialog
......@@ -37,11 +38,12 @@ class MainActivity : BaseActivity(), View.OnClickListener {
var contentLayout: LinearLayout? = null
var tabIvLoan: ImageView? = null
var tabIvRecommend: ImageView? = null
var tabIvMy: ImageView? = null
// 底部标签切换的Fragment
private var mainFragment: Fragment? = null
private var recommendFragment: Fragment? = null
private var myFragment: Fragment? = null
private var currentFragment: Fragment? = null
private var phoneDialog: PhoneDialog? = null
......@@ -54,9 +56,12 @@ class MainActivity : BaseActivity(), View.OnClickListener {
audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
contentLayout = findViewById(R.id.content_layout)
tabIvLoan = findViewById(R.id.tab_iv_loan)
tabIvRecommend = findViewById(R.id.tab_iv_recommend)
tabIvMy = findViewById(R.id.tab_iv_my)
findViewById<View>(R.id.tab_rl_loan).setOnClickListener(this)
findViewById<View>(R.id.tab_iv_recommend).setOnClickListener(this)
findViewById<View>(R.id.tab_rl_my).setOnClickListener(this)
AppConfig.fragmentClickFlag = Constant.FRAGMENT_CLICK_ONE
if (mainFragment == null) {
......@@ -177,7 +182,8 @@ class MainActivity : BaseActivity(), View.OnClickListener {
override fun onClick(view: View) {
when (view.id) {
R.id.tab_rl_loan -> clickTab1Layout()
R.id.tab_rl_my -> clickTab2Layout()
R.id.tab_iv_recommend -> clickTab2Layout()
R.id.tab_rl_my -> clickTab3Layout()
}
}
......@@ -191,22 +197,39 @@ class MainActivity : BaseActivity(), View.OnClickListener {
}
addOrShowFragment(supportFragmentManager.beginTransaction(), mainFragment!!)
tabIvLoan!!.isSelected = true
tabIvRecommend!!.isSelected = false
tabIvMy!!.isSelected = false
}
/**
* 点击第个tab
* 点击第个tab
*/
fun clickTab2Layout() {
AppConfig.fragmentClickFlag = Constant.FRAGMENT_CLICK_TWO
if (recommendFragment == null) {
recommendFragment = RecommendFragment()
}
addOrShowFragment(supportFragmentManager.beginTransaction(), recommendFragment!!)
tabIvLoan!!.isSelected = false
tabIvRecommend!!.isSelected = true
tabIvMy!!.isSelected = false
}
/**
* 点击第三个tab
*/
fun clickTab3Layout() {
AppConfig.fragmentClickFlag = Constant.FRAGMENT_CLICK_THREE
if (myFragment == null) {
myFragment = MyFragment()
}
addOrShowFragment(supportFragmentManager.beginTransaction(), myFragment!!)
tabIvLoan!!.isSelected = false
tabIvRecommend!!.isSelected = false
tabIvMy!!.isSelected = true
}
/**
* 添加或者显示碎片
*
......
......@@ -46,6 +46,11 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Base
TextUtils.equals(getClass().getSimpleName(), "GuideActivity")) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else if (TextUtils.equals(getClass().getSimpleName(), "VideoActivity")) {
StatusBarUtil.transparencyBar(this); //设置状态栏全透明
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
getWindow().setNavigationBarColor(Color.BLACK);
}
} else {
StatusBarUtil.transparencyBar(this); //设置状态栏全透明
StatusBarUtil.StatusBarLightMode(this); //设置白底黑字
......
package com.mints.wisdomclean.ui.adapter
import android.app.Activity
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.mints.wisdomclean.R
/**
* @author Assen
* @date 2023/7/5
* @desc
*/
class FollowAdapter(var activity: Activity) :
BaseQuickAdapter<String, BaseViewHolder>(R.layout.item_follow) {
override fun convert(holder: BaseViewHolder, item: String) {
}
}
\ No newline at end of file
package com.mints.wisdomclean.ui.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.mints.wisdomclean.R
/**
* @author Assen
* @date 2023/7/5
* @desc
*/
class ItemVideoEpisodeAdapter :
BaseQuickAdapter<String, BaseViewHolder>(R.layout.item_item_video_epsiode) {
override fun convert(holder: BaseViewHolder, item: String) {
holder.setText(R.id.item_tv, item)
}
}
\ No newline at end of file
package com.mints.wisdomclean.ui.adapter
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.mints.wisdomclean.ui.fragment.FollowVideoFragment
/**
* @author Assen
* @date 2023/4/11
* @desc
*/
class RecommendPageAdapter(private val fragments: List<Fragment>, fragment: Fragment) :
FragmentStateAdapter(fragment) {
private val fid1 = 111L
private val fid2 = 222L
private val ids = arrayListOf(fid1, fid2)
private val createID = hashSetOf<Long>()
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getItemCount() = fragments.size
override fun createFragment(position: Int): Fragment {
val id = ids[position]
createID.add(id)
return fragments[position]
}
override fun containsItem(itemId: Long): Boolean {
return createID.contains(itemId)
}
}
\ No newline at end of file
package com.mints.wisdomclean.ui.adapter
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.mints.wisdomclean.R
import com.mints.wisdomclean.utils.ToastUtil
/**
* @author Assen
* @date 2023/7/5
* @desc
*/
class VideoEpisodeAdapter :
BaseQuickAdapter<List<String>, BaseViewHolder>(R.layout.item_video_epsiode) {
override fun convert(holder: BaseViewHolder, item: List<String>) {
val rv = holder.getView<RecyclerView>(R.id.item_rv)
rv.layoutManager = GridLayoutManager(context, 6)
val itemVideoEpisodeAdapter = ItemVideoEpisodeAdapter()
rv.adapter = itemVideoEpisodeAdapter
val list = mutableListOf<String>()
itemVideoEpisodeAdapter.addChildClickViewIds(R.id.item_tv)
itemVideoEpisodeAdapter.setOnItemChildClickListener { adapter, view, position ->
ToastUtil.show(context, item[position])
}
list.addAll(item)
itemVideoEpisodeAdapter.setNewInstance(list)
}
override fun getItemCount(): Int {
return data.size % 30
}
}
\ No newline at end of file
package com.mints.wisdomclean.ui.fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager
import com.mints.wisdomclean.R
import com.mints.wisdomclean.ui.adapter.FollowAdapter
import com.mints.wisdomclean.ui.fragment.base.BaseFragment
import kotlinx.android.synthetic.main.fragment_follow_video.*
/**
* @author Assen
* @date 2023/7/5
* @desc 主页 -> 推荐 —> 追剧
*/
class FollowVideoFragment : BaseFragment() {
private val datas = arrayListOf<String>()
lateinit var followAdapter: FollowAdapter
companion object {
fun newInstance(): Fragment {
val args = Bundle()
val fragment = FollowVideoFragment()
fragment.arguments = args
return fragment
}
}
override fun initViewsAndEvents() {
initRecy()
}
override fun getContentViewLayoutID() = R.layout.fragment_follow_video
private fun initRecy() {
datas.add("")
datas.add("")
datas.add("")
val emptyView =
LayoutInflater.from(requireContext()).inflate(R.layout.item_follow_empty, null)
emptyView.findViewById<View>(R.id.btn).setOnClickListener { showToast("去剧场") }
rv_follow.layoutManager = GridLayoutManager(requireContext(), 3)
followAdapter = FollowAdapter(requireActivity())
followAdapter.setEmptyView(emptyView)
followAdapter.setNewInstance(datas)
rv_follow.adapter = followAdapter
}
}
\ No newline at end of file
......@@ -197,7 +197,7 @@ class MainFragment : BaseFragment(), HomeView, View.OnClickListener, OnRefreshLi
}
private fun getTabView(text: String): View {
val view = LayoutInflater.from(requireContext()).inflate(R.layout.item_video_tab, null)
val view = LayoutInflater.from(requireContext()).inflate(R.layout.item_recommend_tab, null)
view.findViewById<TextView>(R.id.item_tv).text = text
return view
}
......
package com.mints.wisdomclean.ui.fragment
import android.view.LayoutInflater
import android.view.View
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import com.mints.wisdomclean.R
import com.mints.wisdomclean.common.AppConfig
import com.mints.wisdomclean.common.Constant
import com.mints.wisdomclean.ui.adapter.RecommendPageAdapter
import com.mints.wisdomclean.ui.fragment.base.BaseFragment
import kotlinx.android.synthetic.main.fragment_recommend.*
/**
* @author Assen
* @date 2023/7/5
* @desc 主页 -> 推荐
*/
class RecommendFragment : BaseFragment() {
private var mSelectTabIndex = -1
private val tabsData = mutableListOf<String>()
private val fragments = mutableListOf<Fragment>()
private var vpAdapter: RecommendPageAdapter? = null
override fun initViewsAndEvents() {
tabsData.add("追剧")
tabsData.add("推荐")
fragments.add(FollowVideoFragment.newInstance())
fragments.add(WatchVideoFragment.newInstance())
vpAdapter = RecommendPageAdapter(fragments, this)
vp2_recommend.adapter = vpAdapter
TabLayoutMediator(tab_recommend, vp2_recommend) { tab, position ->
// 初始化Tab
tab.id = position
tab.customView = getTabView(position)
}.attach()
tab_recommend.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) {
mSelectTabIndex = tab!!.id
updateTab(tab, true, mSelectTabIndex)
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
updateTab(tab, false, mSelectTabIndex)
}
override fun onTabReselected(tab: TabLayout.Tab?) {
}
})
vp2_recommend.offscreenPageLimit = 2
}
override fun getContentViewLayoutID() = R.layout.fragment_recommend
private fun getTabView(position: Int): View {
val view = LayoutInflater.from(requireContext()).inflate(R.layout.item_recommend_tab, null)
view.findViewById<TextView>(R.id.item_tv).text = tabsData[position]
if (position == 0) {
view.findViewById<View>(R.id.item_line).background =
ContextCompat.getDrawable(requireContext(), R.drawable.shape_line_corner_red)
}
return view
}
private fun updateTab(tab: TabLayout.Tab?, isSelected: Boolean, position: Int) {
tab?.customView?.let {
val text = it.findViewById<TextView>(R.id.item_tv)
val line = it.findViewById<View>(R.id.item_line)
line.visibility = if (isSelected) View.VISIBLE else View.INVISIBLE
if (position == 0) {
if (isSelected) {
text.setTextColor(ContextCompat.getColor(requireContext(), R.color.black))
} else {
text.setTextColor(ContextCompat.getColor(requireContext(), R.color.my_color_gray))
}
line.background =
ContextCompat.getDrawable(requireContext(), R.drawable.shape_line_corner_red)
} else {
if (isSelected) {
text.setTextColor(ContextCompat.getColor(requireContext(), R.color.white))
} else {
text.setTextColor(ContextCompat.getColor(requireContext(), R.color.color_8D8F90))
}
line.background =
ContextCompat.getDrawable(requireContext(), R.drawable.shape_line_corner_white)
}
}
}
override fun onResume() {
super.onResume()
if (AppConfig.fragmentClickFlag == Constant.FRAGMENT_CLICK_TWO) {
}
}
}
\ No newline at end of file
package com.mints.wisdomclean.ui.widgets
import android.app.Dialog
import android.content.Context
import android.view.*
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import com.mints.wisdomclean.R
import com.mints.wisdomclean.ui.adapter.VideoEpisodeAdapter
import com.mints.wisdomclean.utils.CommonUtils
/**
* @author Assen
* @date 2023/7/5
* @desc
*/
class VideoEpisodeDialog(context: Context, private val listener: DialogListener) :
Dialog(context, R.style.dialog) {
private val lp: WindowManager.LayoutParams
private val vp2: ViewPager2
private val tab: TabLayout
private val ivClose: ImageView
init {
setContentView(R.layout.dialog_video_episode)
// 设置window属性
lp = window!!.attributes
lp.gravity = Gravity.CENTER
lp.width = WindowManager.LayoutParams.MATCH_PARENT
lp.windowAnimations = R.style.DialogAnimBottom
// lp.dimAmount = 0; // 去背景遮盖
// lp.alpha = 1.0f;//透明效果
window!!.attributes = lp
// 设置外部不可关闭
setCancelable(true)
setCanceledOnTouchOutside(true)
setOnKeyListener { _, i, _ ->
i == KeyEvent.KEYCODE_BACK
}
listener.setDialog(this)
vp2 = findViewById(R.id.vp2_episode)
tab = findViewById(R.id.tab_episode)
ivClose = findViewById(R.id.close_iv)
ivClose.setOnClickListener(listener)
initVp()
}
private fun initVp() {
val data = arrayListOf<String>()
for (i in 1..100) {
data.add("" + i)
}
val subList = CommonUtils.getSubList(30, data)
val adapter = VideoEpisodeAdapter()
adapter.setNewInstance(subList)
vp2.adapter = adapter
TabLayoutMediator(tab, vp2) { tab, position ->
// 初始化Tab
tab.id = position
tab.customView =
getTabView(
"" + subList[position][0] + "-" + subList[position][subList[position].size - 1],
position
)
}.attach()
tab.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) {
updateTab(tab, true)
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
updateTab(tab, false)
}
override fun onTabReselected(tab: TabLayout.Tab?) {
}
})
}
private fun getTabView(text: String, position: Int): View {
val view = LayoutInflater.from(context).inflate(R.layout.item_epsiode_tab, null)
val viewText = view.findViewById<TextView>(R.id.item_tv)
viewText.text = text
if (position == 0) {
viewText.setTextColor(ContextCompat.getColor(context, R.color.red))
}
return view
}
private fun updateTab(tab: TabLayout.Tab?, isSelected: Boolean) {
tab?.customView?.let {
val text = it.findViewById<TextView>(R.id.item_tv)
if (isSelected) {
text.setTextColor(ContextCompat.getColor(context, R.color.red))
} else {
text.setTextColor(ContextCompat.getColor(context, R.color.black))
}
}
}
}
\ No newline at end of file
......@@ -26,6 +26,8 @@ import android.text.TextUtils;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
......@@ -355,4 +357,29 @@ public class CommonUtils {
return source;
}
}
/**
* 将list拆分成指定数量的小list
* 注: 使用的subList方式,返回的是list的内部类,不可做元素的删除,修改,添加操作
*
* @param length 数量
* @param list 大list
*/
public static <T> List<List<T>> getSubList(int length, List<T> list) {
int size = list.size();
int temp = size / length + 1;
boolean result = size % length == 0;
List<List<T>> subList = new ArrayList<>();
for (int i = 0; i < temp; i++) {
if (i == temp - 1) {
if (result) {
break;
}
subList.add(list.subList(length * i, size));
} else {
subList.add(list.subList(length * i, length * (i + 1)));
}
}
return subList;
}
}
......@@ -193,19 +193,20 @@ object TimeRender {
val yearZ = split[0].toInt()
val monthZ = split[1].toInt() - 1
val dayZ = split[2].toInt()
val datePickerDialog = DatePickerDialog(context!!, OnDateSetListener { view, year, monthOfYear, dayOfMonth ->
nqMonth = if (monthOfYear + 1 < 10) {
"0" + (monthOfYear + 1)
} else {
(monthOfYear + 1).toString()
}
nqDay = if (dayOfMonth < 10) {
"0$dayOfMonth"
} else {
dayOfMonth.toString()
}
editText.setText("$year-$nqMonth-$nqDay")
}, yearZ, monthZ, dayZ)
val datePickerDialog =
DatePickerDialog(context!!, OnDateSetListener { view, year, monthOfYear, dayOfMonth ->
nqMonth = if (monthOfYear + 1 < 10) {
"0" + (monthOfYear + 1)
} else {
(monthOfYear + 1).toString()
}
nqDay = if (dayOfMonth < 10) {
"0$dayOfMonth"
} else {
dayOfMonth.toString()
}
editText.setText("$year-$nqMonth-$nqDay")
}, yearZ, monthZ, dayZ)
datePickerDialog.show()
}
......@@ -295,4 +296,16 @@ object TimeRender {
return formatDateDot(now.time)
}
/**
* 是否超过outMin分钟
*
* @param adPreLoadTime 广告预加载时间
* @return true-超过outMin分钟
*/
fun isOverspedMin(adPreLoadTime: Long, outMin: Int): Boolean {
val time = (System.currentTimeMillis() - adPreLoadTime) / (1000 * 60)
// LogUtil.d("PreCsjGroMoreVideoAdManager","adPreLoadTime="+adPreLoadTime+"time="+time);
return time > outMin && adPreLoadTime > 0
}
}
\ No newline at end of file
package com.mints.wisdomclean.video
import android.app.Activity
import android.util.Log
import cn.jzvd.Jzvd
import cn.jzvd.JzvdStd
import com.bumptech.glide.Glide
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.mints.wisdomclean.MintsApplication
import com.mints.wisdomclean.R
/**
* author : ChenWenJie
* email : 1181620038@qq.com
* date : 2020/9/22
* desc : 适配器
*/
class RecommendVideoAdapter(var activity: Activity) :
BaseQuickAdapter<VideoBean, BaseViewHolder>(R.layout.item_video_recommend) {
override fun convert(holder: BaseViewHolder, item: VideoBean) {
//用户名
holder.setText(R.id.username_tv, item.user_name)
//标题
holder.setText(R.id.usertitle_tv, item.video_title)
//缩略图
Glide.with(activity).load(item.video_image)
.into(holder.getView<JzvdStdTikTok>(R.id.jz_video).posterImageView)
//声明 代理服务缓存
val proxy = MintsApplication.StaticParams.getProxy()
//这个缓存下一个
if (holder.layoutPosition + 1 < itemCount) {
val item1 = getItem(holder.layoutPosition + 1)
//缓存下一个 10秒
proxy!!.preLoad(item1.video_path, 10)
}
//缓存当前,播放当前
val proxyUrl = proxy?.getProxyUrl(item.video_path).toString() //设置视
setPlay(holder.getView(R.id.jz_video), proxyUrl)
}
fun setPlay(jzvdStdTikTok: JzvdStdTikTok, path: String) {
Log.e("RecommendVideoAdapter", "$path")
//不保存播放进度
Jzvd.SAVE_PROGRESS = false
//取消播放时在非WIFIDialog提示
Jzvd.WIFI_TIP_DIALOG_SHOWED = true
// 清除某个URL进度
//JZUtils.clearSavedProgress(activity, path)
jzvdStdTikTok.setUp(path, "", JzvdStd.SCREEN_NORMAL)
jzvdStdTikTok.setOnVideoCompletion(onVideoCompletion)
}
private var onVideoCompletion: JzvdStdTikTok.OnVideoCompletion? = null
fun setOnVideoCompletion(onVideoCompletion: JzvdStdTikTok.OnVideoCompletion?) {
this.onVideoCompletion = onVideoCompletion
}
}
\ No newline at end of file
package com.cwj.updownshortvideo
package com.mints.wisdomclean.video
import android.content.Context
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.PagerSnapHelper
import androidx.recyclerview.widget.RecyclerView
import com.mints.wisdomclean.video.OnRecyViewListener
/**
* author : ChenWenJie
......@@ -18,9 +17,7 @@ class RecyViewLayoutManager : LinearLayoutManager {
private var mPagerSnapHelper: PagerSnapHelper? = null
private var mOnRecycleViewListener: OnRecyViewListener? = null
private var mRecyclerView: RecyclerView? = null
private var mDrift //位移,用来判断移动方向
= 0
private var mDrift = 0//位移,用来判断移动方向
private val mChildAttachStateChangeListener: RecyclerView.OnChildAttachStateChangeListener =
object : RecyclerView.OnChildAttachStateChangeListener {
......
package com.mints.wisdomclean.video
import android.app.Dialog
import android.view.View
import androidx.recyclerview.widget.OrientationHelper
import androidx.recyclerview.widget.RecyclerView
import cn.jzvd.Jzvd
import com.cwj.updownshortvideo.*
import com.mints.wisdomclean.R
import com.mints.wisdomclean.ui.activitys.base.BaseActivity
import com.mints.wisdomclean.ui.widgets.DialogListener
import com.mints.wisdomclean.ui.widgets.VideoEpisodeDialog
import kotlinx.android.synthetic.main.activity_video.*
class VideoActivity : BaseActivity() {
class VideoActivity : BaseActivity(), View.OnClickListener {
companion object {
const val VIDEO_ID = "VIDEO_ID"
}
lateinit var adapter: VideoAdapter
private var mCurrentPosition = -1
var videos = ArrayList<VideoBean>()
private var dialog: VideoEpisodeDialog? = null
override fun getContentViewLayoutID() = R.layout.activity_video
override fun initViewsAndEvents() {
......@@ -40,9 +48,9 @@ class VideoActivity : BaseActivity() {
}
fun initView() {
val recyViewLayoutManager = RecyViewLayoutManager(
this, OrientationHelper.VERTICAL
)
fm_bottom.setOnClickListener(this)
val recyViewLayoutManager = RecyViewLayoutManager(this, OrientationHelper.VERTICAL)
recy.layoutManager = recyViewLayoutManager
adapter = VideoAdapter(this)
recy.adapter = adapter
......@@ -123,13 +131,13 @@ class VideoActivity : BaseActivity() {
}
// override fun onBackPressed() {
// if (Jzvd.backPress()) {
// Jzvd.releaseAllVideos()
// return
// }
// super.onBackPressed()
// }
override fun onBackPressed() {
if (Jzvd.backPress()) {
Jzvd.releaseAllVideos()
return
}
super.onBackPressed()
}
fun initData() {
videos.add(
......@@ -240,4 +248,26 @@ class VideoActivity : BaseActivity() {
)
}
override fun onClick(v: View?) {
when (v?.id) {
R.id.close_iv -> {
finish()
}
R.id.fm_bottom -> {
if (dialog != null) {
dialog!!.show()
} else {
dialog = VideoEpisodeDialog(this, object : DialogListener() {
override fun onClick(dialog: Dialog?, v: View?) {
super.onClick(dialog, v)
dialog?.dismiss()
}
})
dialog?.show()
}
}
else -> {}
}
}
}
\ No newline at end of file
......@@ -20,10 +20,6 @@ import com.mints.wisdomclean.R
class VideoAdapter(var activity: Activity) :
BaseQuickAdapter<VideoBean, BaseViewHolder>(R.layout.item_video) {
override fun convert(holder: BaseViewHolder, item: VideoBean) {
//圆形用户头像
val requestOptions = RequestOptions.circleCropTransform()
Glide.with(activity).load(item.user_image).apply(requestOptions)
.into(holder.getView(R.id.user_iv))
//用户名
holder.setText(R.id.username_tv, item.user_name)
//标题
......@@ -44,7 +40,6 @@ class VideoAdapter(var activity: Activity) :
//缓存当前,播放当前
var proxyUrl = proxy?.getProxyUrl(item.video_path).toString() //设置视
setPlay(holder.getView(R.id.jz_video), proxyUrl)
}
......@@ -57,7 +52,7 @@ class VideoAdapter(var activity: Activity) :
Jzvd.WIFI_TIP_DIALOG_SHOWED = true
// 清除某个URL进度
//JZUtils.clearSavedProgress(activity, path)
jzvdStdTikTok.setUp(path, "", JzvdStd.SCREEN_FULLSCREEN)
jzvdStdTikTok.setUp(path, "", JzvdStd.SCREEN_NORMAL)
jzvdStdTikTok.setOnVideoCompletion(onVideoCompletion)
}
......
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="30dp" />
<solid android:color="@color/half_transparent" />
</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:radius="2dp" />
<solid android:color="@color/red"/>
</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:radius="2dp" />
<solid android:color="@color/white" />
</shape>
\ No newline at end of file
......@@ -44,6 +44,22 @@
android:src="@drawable/home_tab_home_selector" />
</LinearLayout>
<LinearLayout
android:id="@+id/tab_rl_recommend"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/tab_iv_recommend"
android:layout_width="30dp"
android:layout_height="30dp"
android:contentDescription="@null"
android:src="@drawable/home_tab_home_selector" />
</LinearLayout>
<LinearLayout
android:id="@+id/tab_rl_my"
android:layout_width="0dp"
......
......@@ -3,11 +3,64 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
android:orientation="vertical"
tools:context=".video.VideoActivity">
<ImageView
android:id="@+id/close_iv"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:src="@mipmap/ic_arrow_back" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recy"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent"
android:layout_marginBottom="50dp" />
<FrameLayout
android:id="@+id/fm_bottom"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="bottom">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/dp_40"
android:layout_gravity="center"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:background="@drawable/shape_half_trans"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="@dimen/dp_10"
android:paddingEnd="@dimen/dp_10">
<ImageView
android:layout_width="26dp"
android:layout_height="26dp"
android:src="@mipmap/ic_call_wx" />
<TextView
android:id="@+id/episode_tv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_weight="1"
android:text="共100集 已完结 >"
android:textColor="@color/white" />
<ImageView
android:layout_width="26dp"
android:layout_height="26dp"
android:rotation="180"
android:src="@mipmap/ic_arrow_bottom" />
</LinearLayout>
</FrameLayout>
</FrameLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@drawable/shape_tab_friends"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/dp_40"
android:layout_marginTop="10dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="10dp"
android:paddingEnd="@dimen/dp_10">
<TextView
android:id="@+id/title_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="霸道总裁爱上我"
android:textColor="@color/black" />
<TextView
android:id="@+id/label_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_10"
android:background="@drawable/shape_green"
android:padding="2dp"
android:text="已完结"
android:textColor="@color/gray"
android:textSize="12sp" />
<View
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<ImageView
android:id="@+id/close_iv"
android:layout_width="20dp"
android:layout_height="wrap_content"
android:src="@mipmap/ic_close" />
</LinearLayout>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_episode"
android:layout_width="match_parent"
android:layout_height="36dp"
app:tabBackground="@null"
app:tabIndicatorHeight="0dp"
app:tabMode="scrollable"
app:tabRippleColor="@null" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/vp2_episode"
android:layout_width="match_parent"
android:layout_height="320dp" />
</LinearLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="68dp"
android:background="@color/white">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_follow"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
\ No newline at end of file
......@@ -107,14 +107,14 @@
android:id="@+id/tablayout"
android:layout_width="wrap_content"
android:layout_height="48dp"
app:tabBackground="@color/full_transparent"
app:tabBackground="@null"
app:tabIndicatorHeight="0dp"
app:tabPaddingStart="6dp"
app:tabPaddingEnd="6dp"
app:tabMaxWidth="200dp"
app:tabMinWidth="20dp"
app:tabMode="scrollable"
app:tabRippleColor="@color/full_transparent" />
app:tabRippleColor="@null" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/vp2"
......
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/vp2_recommend"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_recommend"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
app:tabBackground="@null"
app:tabIndicatorHeight="0dp"
app:tabMode="fixed"
app:tabRippleColor="@null" />
</FrameLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recy"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="30dp" />
</FrameLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/item_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/black"
android:textSize="14sp" />
</LinearLayout>
\ 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">
<ImageView
android:id="@+id/image_iv"
android:layout_width="100dp"
android:layout_height="120dp"
android:src="@mipmap/ic_launcher_main"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="6dp"
android:layout_marginBottom="10dp"
android:text="已完结"
android:textColor="@color/white"
app:layout_constraintBottom_toBottomOf="@id/image_iv"
app:layout_constraintEnd_toEndOf="@id/image_iv" />
<TextView
android:id="@+id/title_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="重回80年代"
android:textColor="@color/black"
app:layout_constraintStart_toStartOf="@id/image_iv"
app:layout_constraintTop_toBottomOf="@id/image_iv" />
<TextView
android:id="@+id/info_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="重回80年代"
android:textColor="@color/gray"
android:textSize="12sp"
app:layout_constraintStart_toStartOf="@id/image_iv"
app:layout_constraintTop_toBottomOf="@id/title_tv" />
</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">
<TextView
android:id="@+id/info_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="暂无在追剧"
android:textColor="@color/gray"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btn"
android:layout_width="120dp"
android:layout_height="40dp"
android:layout_marginTop="10dp"
android:background="@drawable/shape_red"
android:elevation="2dp"
android:text="去剧场"
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/info_tv" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginStart="2dp"
android:layout_marginEnd="2dp"
android:layout_marginBottom="@dimen/dp_4"
android:background="@drawable/shape_btn_enabled">
<TextView
android:id="@+id/item_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="1"
android:textColor="@color/black"
android:textSize="16sp" />
</FrameLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:orientation="vertical">
<TextView
android:id="@+id/item_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_8D8F90"
android:textSize="14sp" />
<View
android:id="@+id/item_line"
android:layout_width="20dp"
android:layout_height="2dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="6dp" />
</LinearLayout>
\ No newline at end of file
......@@ -19,18 +19,11 @@
android:id="@+id/ll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginStart="15dp"
android:orientation="horizontal"
app:layout_constraintBottom_toTopOf="@id/usertitle_tv"
app:layout_constraintLeft_toLeftOf="parent">
<ImageView
android:id="@+id/user_iv"
android:layout_width="40dp"
android:layout_height="40dp"
android:padding="2dp"
android:scaleType="fitXY" />
<TextView
android:id="@+id/username_tv"
android:layout_width="wrap_content"
......@@ -48,7 +41,7 @@
android:id="@+id/usertitle_tv"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_marginLeft="10dp"
android:layout_marginStart="15dp"
android:ellipsize="end"
android:gravity="center|left"
android:maxEms="14"
......@@ -57,70 +50,35 @@
android:textColor="#fff"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" />
app:layout_constraintLeft_toLeftOf="parent"
tools:ignore="RtlHardcoded" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="15dp"
android:gravity="center"
app:layout_constraintBottom_toTopOf="@id/usertitle_tv"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@id/ll"
app:layout_constraintRight_toRightOf="parent">
<ImageView
android:id="@+id/zan_iv"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_marginTop="10dp"
android:scaleType="fitXY"
android:id="@+id/zan_iv"
android:src="@drawable/ic_aixin" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="199.9w"
android:id="@+id/zan_num_tv"
android:textColor="#fff"
android:textSize="14sp" />
<ImageView
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_marginTop="10dp"
android:scaleType="fitXY"
android:src="@drawable/ic_pl" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="12312"
android:id="@+id/zan_price_tv"
android:textColor="#fff"
android:textSize="14sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="199.9w"
android:textColor="#fff"
android:textSize="14sp" />
<ImageView
android:id="@+id/share_iv"
android:layout_width="35dp"
android:layout_height="35dp"
android:scaleType="fitXY"
android:src="@drawable/ic_zhunfa" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#fff"
android:text="345"
android:textSize="14sp" />
</LinearLayout>
</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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/item_rv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#77090909">
<com.mints.wisdomclean.video.JzvdStdTikTok
android:id="@+id/jz_video"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent">
<TextView
android:id="@+id/username_tv"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="15dp"
android:ellipsize="end"
android:gravity="center"
android:maxEms="9"
android:maxLines="1"
android:text="飞翔的企鹅"
android:textColor="#fff"
android:textSize="16sp" />
<TextView
android:id="@+id/usertitle_tv"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_marginStart="15dp"
android:ellipsize="end"
android:gravity="center|left"
android:maxEms="14"
android:maxLines="3"
android:text="飞翔的企鹅飞翔的企鹅飞翔的企鹅飞翔的企鹅飞翔/n的企鹅飞翔的企鹅"
android:textColor="#fff"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
tools:ignore="RtlHardcoded" />
<LinearLayout
android:id="@+id/ll_bottom"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginBottom="2dp"
android:background="@color/half_transparent"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="15dp"
android:paddingEnd="15dp">
<ImageView
android:layout_width="26dp"
android:layout_height="26dp"
android:src="@mipmap/ic_call_wx" />
<TextView
android:id="@+id/episode_tv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_weight="1"
android:text="共100集 已完结 >"
android:textColor="@color/white" />
<TextView
android:layout_width="wrap_content"
android:layout_height="30dp"
android:background="@drawable/shape_half_trans"
android:gravity="center"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:text="下一集"
android:textColor="@color/white"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_collect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="15dp"
android:gravity="center"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@id/ll"
app:layout_constraintRight_toRightOf="parent">
<ImageView
android:id="@+id/zan_iv"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_marginTop="10dp"
android:scaleType="fitXY"
android:src="@drawable/ic_aixin" />
<TextView
android:id="@+id/zan_num_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="199.9w"
android:textColor="@color/white"
android:textSize="14sp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
......@@ -10,6 +10,7 @@
<color name="color_939AA3">#373737</color>
<color name="color_FF7563">#FF7563</color>
<color name="full_transparent">#00000000</color>
<color name="half_transparent">#80000000</color>
<color name="title_bg">#2B3238</color>
<color name="status_bg">#002444</color>
<color name="loading_bg">#600c224b</color>
......
......@@ -46,4 +46,5 @@ RELEASE_UMENG_KEY=63c0fd97d64e68613917170f
RELEASE_TALKING_DATA_KEY="8B400B45ABBB47D882B2C2E69E6A3662"
GROMORE_APP_ID="5404192"
GROMORE_SPLASH_CODE="102371299"
\ No newline at end of file
GROMORE_SPLASH_CODE="102371299"
GROMORE_VIDEO_CODE="1"
\ 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