Commit 61277593 authored by wanglei's avatar wanglei

...

parent 097785f2
......@@ -109,6 +109,8 @@ dependencies {
//第三方UI控件
implementation("io.github.cymchad:BaseRecyclerViewAdapterHelper4:4.1.4")
implementation("io.github.youth5201314:banner:2.2.3")
implementation("com.github.angcyo.DslTablayout:TabLayout:3.6.4")
implementation("com.github.angcyo.DslTablayout:ViewPager2Delegate:3.6.4")
//firebase
implementation(platform("com.google.firebase:firebase-bom:32.3.1"))
......
......@@ -23,7 +23,9 @@
android:supportsRtl="true"
android:theme="@style/Theme.LocalWeatherWhite"
tools:targetApi="31">
<activity
android:name=".ui.category.CategoryActivity"
android:exported="false" />
<activity
android:name=".ui.start.StartActivity"
android:exported="true"
......@@ -35,14 +37,9 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.main.MainActivity"
android:exported="true">
</activity>
android:exported="true"></activity>
<activity
android:name=".ui.play.PlayFullActivity"
android:exported="false"
......
......@@ -163,11 +163,11 @@ class MyApplication : Application() {
Thread {
val config = AppPreferences.getInstance().getString("config", "")
if (config.isNotEmpty()) {
initConfig(config)
// initConfig(config)
}
InstallHelps.init {
initRemoteConfig()
// initRemoteConfig()
}
}.start()
}
......@@ -254,7 +254,7 @@ class MyApplication : Application() {
}
private fun initConfig(config: String) {
LogEx.logDebug(TAG, "initConfig config=$config")
// kotlin.runCatching {
val configBean = Gson().fromJson(config, ConfigBean::class.java)
......
package com.base.appzxhy.ui.adapter
import android.content.Context
import android.view.ViewGroup
import com.base.appzxhy.R
import com.base.appzxhy.databinding.ItemShortplayStyle4Binding
import com.base.appzxhy.utils.XmlEx.inflate
import com.bumptech.glide.Glide
import com.bytedance.sdk.shortplay.api.ShortPlay
import com.chad.library.adapter4.BaseQuickAdapter
class ShortPlayAdapter(
val layout: Int
) : BaseQuickAdapter<ShortPlay, CommonViewHolder>() {
var itemClick: ((shortList: ShortPlay) -> Unit)? = null
override fun onBindViewHolder(holder: CommonViewHolder, position: Int, item: ShortPlay?) {
item ?: return
val context = holder.itemView.context
when (layout) {
R.layout.item_shortplay_style_4 -> {
val binding = ItemShortplayStyle4Binding.bind(holder.itemView)
Glide.with(context).load(item.coverImage).into(binding.iv)
binding.tvName.text = item.title
binding.root.setOnClickListener {
itemClick?.invoke(item)
}
}
}
}
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): CommonViewHolder {
return CommonViewHolder(layout.inflate(parent))
}
}
\ No newline at end of file
package com.base.appzxhy.ui.category
import android.widget.TextView
import androidx.activity.addCallback
import androidx.core.content.ContextCompat
import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.angcyo.tablayout.delegate2.ViewPager2Delegate
import com.base.appzxhy.R
import com.base.appzxhy.base.BaseActivity
import com.base.appzxhy.databinding.ActivityCategoryBinding
import com.base.appzxhy.ui.vm.ShortPlayViewModel
import com.base.appzxhy.utils.BarUtils
import com.base.appzxhy.utils.LogEx
import com.base.appzxhy.utils.XmlEx.inflate
import com.bytedance.sdk.shortplay.api.ShortPlay
import com.gyf.immersionbar.ktx.immersionBar
class CategoryActivity : BaseActivity<ActivityCategoryBinding>(ActivityCategoryBinding::inflate) {
val viewModel by lazy(LazyThreadSafetyMode.NONE) {
ViewModelProvider(this)[ShortPlayViewModel::class.java]
}
private var pageAdapter: FragmentStateAdapter? = null
override fun initView() {
super.initView()
binding.root.updatePadding(top = BarUtils.getStatusBarHeight())
binding.dslTabLayout.tabIndicator.indicatorDrawable =
ContextCompat.getDrawable(this, R.drawable.indicator_bottom_line)
binding.dslTabLayout.tabIndicator.indicatorEnableFlow = true
binding.dslTabLayout.tabIndicator.ignoreChildPadding = true
val textLength = resources.getDimensionPixelOffset(R.dimen.dp_5)
viewModel.getCategoryList("en") { list ->
runOnUiThread {
list.forEach {
val view = R.layout.tab_text.inflate(this)
view.findViewById<TextView>(R.id.tv).text = it.name
binding.dslTabLayout.addView(view)
}
binding.dslTabLayout.configTabLayoutConfig {
onSelectIndexChange = { fromIndex, selectIndexList, reselect, fromUser ->
val toIndex = selectIndexList.first()
val name = list[toIndex].name
LogEx.logDebug(TAG, "length=${name.length}")
binding.dslTabLayout.tabIndicator.indicatorWidth = name.length * textLength
}
}
ViewPager2Delegate.install(binding.viewPager2, binding.dslTabLayout)
initViewPager2(list)
}
}
}
private fun initViewPager2(list: List<ShortPlay.ShortPlayCategory>) {
pageAdapter = object : FragmentStateAdapter(this) {
override fun getItemCount(): Int {
return list.size
}
override fun createFragment(position: Int): Fragment {
val category = list[position]
return CategoryPageFragment(category)
}
}
binding.viewPager2.run {
isUserInputEnabled = true
//https://www.jianshu.com/p/f69bd30cf5b0
//FragmentStateAdapter 这里必须传人fragment
adapter = pageAdapter
}
}
override fun initListener() {
super.initListener()
onBackPressedDispatcher.addCallback {
finish()
}
binding.flBack.setOnClickListener {
onBackPressedDispatcher.onBackPressed()
}
}
override fun configSystemBar() {
immersionBar {
statusBarColor("#000000")
statusBarDarkFont(true)
}
}
}
\ No newline at end of file
package com.base.appzxhy.ui.category
import com.base.appzxhy.BuildConfig
import com.base.appzxhy.R
import com.base.appzxhy.base.BaseFragment
import com.base.appzxhy.databinding.FragmentCategoryPageBinding
import com.base.appzxhy.ui.adapter.ShortPlayAdapter
import com.base.appzxhy.utils.ToastUtils.toast
import com.bytedance.sdk.shortplay.api.ShortPlay
class CategoryPageFragment(
val category: ShortPlay.ShortPlayCategory
) : BaseFragment<FragmentCategoryPageBinding>(FragmentCategoryPageBinding::inflate) {
private var adapter: ShortPlayAdapter? = null
override fun initView() {
super.initView()
adapter = ShortPlayAdapter(R.layout.item_shortplay_style_4)
binding.rv.adapter = adapter
adapter?.itemClick = ::shortPlayClick
}
private fun shortPlayClick(shortPlay: ShortPlay) {
if (BuildConfig.DEBUG) {
requireContext().toast("${shortPlay.title}")
}
}
override fun onResumeOneShoot() {
super.onResumeOneShoot()
val activity = requireActivity() as CategoryActivity?
activity?.viewModel?.getFeedListByCategoryIds(categoryIds = listOf(category.id)) { list ->
activity.runOnUiThread {
adapter?.submitList(list)
}
}
}
override fun initListener() {
super.initListener()
}
}
\ No newline at end of file
......@@ -15,6 +15,10 @@ class ShortPlayCategoryAdapter(
val category: String = "",
val shortList: List<ShortPlay>
) : BaseQuickAdapter<Any, CommonViewHolder>() {
var itemClick: ((shortPlay: ShortPlay) -> Unit)? = null
var categoryClick: (() -> Unit)? = null
override fun getItemCount(items: List<Any>): Int {
return 1
}
......@@ -27,6 +31,9 @@ class ShortPlayCategoryAdapter(
binding.rv.adapter = adapter
adapter.submitList(shortList)
}
binding.root.setOnClickListener {
categoryClick?.invoke()
}
}
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): CommonViewHolder {
......@@ -37,8 +44,11 @@ class ShortPlayCategoryAdapter(
override fun onBindViewHolder(holder: CommonViewHolder, position: Int, item: ShortPlay?) {
item ?: return
val binding = ItemShortplayStyle3Binding.bind(holder.itemView)
binding.tvName.text=item.title
binding.tvName.text = item.title
Glide.with(context).load(item.coverImage).into(binding.iv)
binding.root.setOnClickListener {
itemClick?.invoke(item)
}
}
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): CommonViewHolder {
......
......@@ -19,6 +19,8 @@ class ShortPlayColumnsAdapter(
val shortList: List<ShortPlay>
) : BaseQuickAdapter<Any, CommonViewHolder>() {
var itemClick: ((shortPlay: ShortPlay) -> Unit)? = null
override fun getItemCount(items: List<Any>): Int {
return 1
}
......@@ -27,7 +29,7 @@ class ShortPlayColumnsAdapter(
val binding = ItemShortplayColumnsBinding.bind(holder.itemView)
binding.tvCategory.text = category
if (binding.rv.adapter == null) {
val adapter = ShortPlayAdapter()
val adapter = InnerShortPlayAdapter()
binding.rv.adapter = adapter
adapter.submitList(shortList)
}
......@@ -38,7 +40,7 @@ class ShortPlayColumnsAdapter(
return CommonViewHolder(R.layout.item_shortplay_columns.inflate(parent))
}
inner class ShortPlayAdapter() : BaseQuickAdapter<ShortPlay, CommonViewHolder>() {
inner class InnerShortPlayAdapter() : BaseQuickAdapter<ShortPlay, CommonViewHolder>() {
override fun onBindViewHolder(holder: CommonViewHolder, position: Int, item: ShortPlay?) {
item ?: return
val binding = ItemShortplayStyle1Binding.bind(holder.itemView)
......@@ -48,6 +50,9 @@ class ShortPlayColumnsAdapter(
kotlin.runCatching {
binding.tvCategory.text = item.categories[0].name
}
binding.root.setOnClickListener {
itemClick?.invoke(item)
}
}
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): CommonViewHolder {
......
......@@ -3,41 +3,87 @@ package com.base.appzxhy.ui.main
import android.content.Intent
import androidx.core.view.updatePadding
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.RecyclerView
import com.base.appzxhy.BuildConfig
import com.base.appzxhy.base.BaseFragment
import com.base.appzxhy.databinding.FragmentHomeBinding
import com.base.appzxhy.ui.category.CategoryActivity
import com.base.appzxhy.ui.concatAdapter.BannerAdapter
import com.base.appzxhy.ui.concatAdapter.ShortPlayCategoryAdapter
import com.base.appzxhy.ui.concatAdapter.ShortPlayColumnsAdapter
import com.base.appzxhy.ui.play.PlayFullActivity
import com.base.appzxhy.ui.vm.ShortPlayViewModel
import com.base.appzxhy.utils.BarUtils
import com.base.appzxhy.utils.LogEx
import com.base.appzxhy.utils.ToastUtils.toast
import com.bytedance.sdk.shortplay.api.ShortPlay
import com.google.gson.Gson
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
class HomeFragment : BaseFragment<FragmentHomeBinding>(FragmentHomeBinding::inflate) {
private var contactAdapter: ConcatAdapter? = null
private var bannerAdapter: BannerAdapter? = null
private var columnsAdapter: ShortPlayColumnsAdapter? = null
private val viewModel by lazy(LazyThreadSafetyMode.NONE) {
ViewModelProvider(this)[ShortPlayViewModel::class.java]
}
override fun initView() {
super.initView()
binding.root.updatePadding(top = BarUtils.getStatusBarHeight())
contactAdapter = ConcatAdapter()
binding.rv.adapter = contactAdapter
initBannerAdapter()
initNewShortAdapter()
lifecycleScope.launch {
viewModel.homeCategoryFlow.collectLatest { id ->
when (id) {
0L -> initNewShortAdapter()
else -> initCategoryShortAdapter(listOf(id))
}
}
}
binding.rv.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
if (recyclerView.computeVerticalScrollExtent() + recyclerView.computeVerticalScrollOffset() >= recyclerView.computeVerticalScrollRange()) {
LogEx.logDebug(TAG, "loadMore")
viewModel.sendHomeCategoryFlow()
}
}
})
}
private fun initCategoryShortAdapter(categoryIds: List<Long>) {
viewModel.getFeedListByCategoryIds(categoryIds, null) { list ->
if (list.size > 4) {
val activity = requireActivity() as MainActivity?
activity?.runOnUiThread {
val ids = categoryIds[0]
val categoryTitle = viewModel.categoryTitle(requireContext(), ids)
val categoryAdapter = ShortPlayCategoryAdapter(categoryTitle, list)
categoryAdapter.itemClick = ::shortPlayClick
categoryAdapter.categoryClick = {
jumpCategory(ids)
}
contactAdapter?.addAdapter(categoryAdapter)
}
}
}
}
private fun initBannerAdapter() {
viewModel.getPopularDrama { list ->
val activity = requireActivity() as MainActivity?
activity?.runOnUiThread {
LogEx.logDebug(TAG, "list=${list.size}")
// LogEx.logDebug(TAG, "list=${list.size}")
bannerAdapter = BannerAdapter(list)
bannerAdapter?.let {
it.paletteAction = {
......@@ -56,9 +102,16 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>(FragmentHomeBinding::infl
}
override fun onResumeOneShoot() {
super.onResumeOneShoot()
binding.root.postDelayed({
bannerAdapter?.setBannerAutoLoop(true)
}, 1500)
}
override fun onResume() {
super.onResume()
bannerAdapter?.setBannerAutoLoop(true)
}
override fun onPause() {
......@@ -68,16 +121,32 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>(FragmentHomeBinding::infl
private fun initNewShortAdapter() {
viewModel.getNewDrama { list ->
val activity = requireActivity() as MainActivity?
activity?.runOnUiThread {
val adapter = ShortPlayColumnsAdapter("New Short", list)
contactAdapter?.addAdapter(adapter)
if (list.size > 4) {
val activity = requireActivity() as MainActivity?
activity?.runOnUiThread {
columnsAdapter = ShortPlayColumnsAdapter("New Short", list)
columnsAdapter?.let { contactAdapter?.addAdapter(it) }
}
}
viewModel.sendHomeCategoryFlow()
}
}
override fun initListener() {
super.initListener()
columnsAdapter?.itemClick = ::shortPlayClick
}
private fun shortPlayClick(item: ShortPlay) {
if (BuildConfig.DEBUG) {
requireContext().toast("${item.title}")
}
}
private fun jumpCategory(ids: Long) {
val activity = requireActivity() as MainActivity?
activity ?: return
activity.startActivity(Intent(activity, CategoryActivity::class.java).apply {
putExtra("data", ids)
})
}
}
\ No newline at end of file
package com.base.appzxhy.ui.vm
import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.base.appzxhy.R
import com.base.appzxhy.utils.LogEx
import com.bytedance.sdk.shortplay.api.PSSDK
import com.bytedance.sdk.shortplay.api.PSSDK.CategoryListResultListener
import com.bytedance.sdk.shortplay.api.PSSDK.FeedListLoadResult
import com.bytedance.sdk.shortplay.api.PSSDK.FeedListResultListener
import com.bytedance.sdk.shortplay.api.ShortPlay
import com.bytedance.sdk.shortplay.api.ShortPlay.ShortPlayCategory
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import java.util.concurrent.atomic.AtomicBoolean
class ShortPlayViewModel : ViewModel() {
private val TAG = "ShortPlayViewModel"
companion object {
const val CATEGORY_MALE_ID = 1L//男频
const val CATEGORY_FEMALE_ID = 2L//女频
const val CATEGORY_CITY_ID = 3L//都市
const val CATEGORY_SUSPENSE_ID = 4L//悬疑
const val CATEGORY_MODERN_ID = 5L//现代
const val CATEGORY_ANCIENT_ID = 6L//古代
const val CATEGORY_MILITARY_ID = 7L//军事
const val CATEGORY_FANTASY_ID = 8L//玄幻
const val CATEGORY_BLOOD_ID = 9L//热血
const val CATEGORY_HISTORY_ID = 10L//历史
const val CATEGORY_COMEDY_ID = 11L//喜剧
const val CATEGORY_ACTION_ID = 12L//动作
const val CATEGORY_ACG_ID = 13L//二次元
const val CATEGORY_OTHERS_ID = 14L//其他
}
private val categoryLoading = AtomicBoolean(false)
var homeCategoryFlow = MutableStateFlow(-1L)
private val homeCategoryList =
arrayListOf(
0,
CATEGORY_CITY_ID,
CATEGORY_MODERN_ID,
CATEGORY_COMEDY_ID,
CATEGORY_ANCIENT_ID,
CATEGORY_ACTION_ID,
CATEGORY_FANTASY_ID,
CATEGORY_BLOOD_ID,
CATEGORY_SUSPENSE_ID,
CATEGORY_MILITARY_ID,
CATEGORY_HISTORY_ID,
CATEGORY_ACG_ID,
CATEGORY_OTHERS_ID
)
fun sendHomeCategoryFlow() {
if (homeCategoryList.isEmpty()) return
if (categoryLoading.get()) return
val nextCategory = homeCategoryList[0]
homeCategoryList.removeAt(0)
LogEx.logDebug(TAG, "nextCategory=$nextCategory")
viewModelScope.launch {
homeCategoryFlow.emit(nextCategory)
}
}
/**
* 获取热门短剧列表
*/
......@@ -57,42 +107,65 @@ class ShortPlayViewModel : ViewModel() {
})
}
/**
* 加载分类
* 获取指定分类或短剧的列表
*/
fun loadShortPlayCategory() = viewModelScope.launch(Dispatchers.IO) {
LogEx.logDebug(TAG, "loadShortPlayCategory")
val lang = "en"
PSSDK.requestCategoryList(lang, object : CategoryListResultListener {
override fun onFail(errorInfo: PSSDK.ErrorInfo) {
LogEx.logDebug(TAG, "loadShortPlayCategory errorInfo = [$errorInfo]")
fun getFeedListByCategoryIds(
categoryIds: List<Long>? = null,
shortPlayIds: List<Long>? = null,
index: Int = 1,
count: Int = 12,
uiAction: (list: List<ShortPlay>) -> Unit
) {
categoryLoading.set(true)
PSSDK.requestFeedListByCategoryIds(categoryIds, shortPlayIds, index, count, object : FeedListResultListener {
override fun onFail(errorInfo: PSSDK.ErrorInfo?) {
LogEx.logDebug(TAG, "requestFeedListByCategoryIds ${errorInfo?.msg} ${errorInfo?.code}")
categoryLoading.set(false)
}
override fun onSuccess(result: FeedListLoadResult<ShortPlayCategory>) {
launch(Dispatchers.Main) {
LogEx.logDebug(TAG, "loadShortPlayCategory size=${result.dataList}")
val list = result.dataList
val hasMore = result.hasMore
val fromCache = result.fromCache
}
override fun onSuccess(result: FeedListLoadResult<ShortPlay>?) {
result?.dataList?.let { uiAction.invoke(it) }
categoryLoading.set(false)
}
})
}
fun loadShortPlay() = viewModelScope.launch(Dispatchers.IO) {
val resultListener: FeedListResultListener = object : FeedListResultListener {
override fun onFail(errorInfo: PSSDK.ErrorInfo) {
LogEx.logDebug(TAG, "loadShortPlay errorInfo code=${errorInfo.code} msg=${errorInfo.msg}")
fun categoryTitle(context: Context, ids: Long): String {
return when (ids) {
CATEGORY_MALE_ID -> context.getString(R.string.male)
CATEGORY_FEMALE_ID -> context.getString(R.string.female)
CATEGORY_CITY_ID -> context.getString(R.string.city)
CATEGORY_SUSPENSE_ID -> context.getString(R.string.suspense)
CATEGORY_MODERN_ID -> context.getString(R.string.modern)
CATEGORY_ANCIENT_ID -> context.getString(R.string.ancient)
CATEGORY_MILITARY_ID -> context.getString(R.string.military)
CATEGORY_FANTASY_ID -> context.getString(R.string.fantasy)
CATEGORY_BLOOD_ID -> context.getString(R.string.blood)
CATEGORY_HISTORY_ID -> context.getString(R.string.history)
CATEGORY_COMEDY_ID -> context.getString(R.string.comedy)
CATEGORY_ACTION_ID -> context.getString(R.string.action)
CATEGORY_ACG_ID -> context.getString(R.string.acg)
CATEGORY_OTHERS_ID -> context.getString(R.string.others)
else -> ""
}
}
/**
* 获取分类标签接口
*/
fun getCategoryList(
language: String,
uiAction: (list: List<ShortPlay.ShortPlayCategory>) -> Unit
) {
PSSDK.requestCategoryList(language, object : PSSDK.CategoryListResultListener {
override fun onFail(errorInfo: PSSDK.ErrorInfo?) {
LogEx.logDebug(TAG, "requestNewDrama ${errorInfo?.msg} ${errorInfo?.code}")
}
override fun onSuccess(result: FeedListLoadResult<ShortPlay>) {
launch(Dispatchers.Main) {
val hasMore = result.hasMore
val list = result.dataList
}
override fun onSuccess(result: FeedListLoadResult<ShortPlay.ShortPlayCategory>?) {
result?.dataList?.let { uiAction.invoke(it) }
}
}
})
}
}
\ 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="20dp" />
<solid android:color="@color/white" />
</shape>
\ 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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
android:orientation="vertical"
tools:context=".ui.category.CategoryActivity"
tools:ignore="Orientation">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/clTop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp">
<FrameLayout
android:id="@+id/flBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/fanhui"
tools:ignore="ContentDescription" />
</FrameLayout>
<LinearLayout
android:id="@+id/llSearch"
android:layout_width="0dp"
android:layout_height="45dp"
android:layout_marginEnd="16dp"
android:background="@drawable/bg_stroke_61ffffff_10"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="@id/flBack"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/flBack"
app:layout_constraintTop_toTopOf="@id/flBack">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="15dp"
android:src="@mipmap/h_shousuo"
tools:ignore="ContentDescription" />
<EditText
android:id="@+id/editSearch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginHorizontal="13dp"
android:background="@null"
android:singleLine="true"
android:textColor="#80FFFFFF"
android:textColorHint="#80FFFFFF"
android:textSize="17sp"
tools:hint="Snatched a Billionaire to be My H..."
tools:ignore="Autofill,LabelFor,TextFields,TouchTargetSizeCheck,VisualLintTextFieldSize" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<com.angcyo.tablayout.DslTabLayout
android:id="@+id/dslTabLayout"
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_marginTop="8dp"
app:tab_default_index="0"
app:tab_deselect_color="#99FFFFFF"
app:tab_draw_indicator="true"
app:tab_indicator_color="#ffffff"
app:tab_indicator_height="2dp"
app:tab_indicator_width="WRAP_CONTENT"
app:tab_item_is_equ_width="false"
app:tab_select_color="@color/white">
</com.angcyo.tablayout.DslTabLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
\ No newline at end of file
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.category.CategoryPageFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="3"
tools:listitem="@layout/item_shortplay_style_4" />
</FrameLayout>
\ No newline at end of file
......@@ -11,6 +11,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="16dp"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"
......@@ -18,6 +19,16 @@
app:layout_constraintTop_toTopOf="parent"
tools:text="Second Chance" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:src="@mipmap/jiantou"
app:layout_constraintBottom_toBottomOf="@id/tvCategory"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tvCategory"
tools:ignore="ContentDescription" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
......
<?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="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="4dp"
android:layout_columnWeight="1"
android:layout_marginVertical="8dp"
tools:background="@color/black">
<androidx.cardview.widget.CardView
android:id="@+id/card"
android:layout_width="108dp"
android:layout_height="142dp"
app:cardCornerRadius="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/iv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
tools:ignore="ContentDescription" />
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/tvName"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginBottom="5dp"
android:maxLines="2"
android:textColor="@color/white"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/card"
tools:ignore="TextSizeCheck"
tools:text="The Quarterback Next Door" />
</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"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingHorizontal="12dp"
android:paddingVertical="6dp"
android:text="Popular"
android:textColor="#99FFFFFF"
android:textSize="16sp"
tools:background="@color/black">
</TextView>
\ No newline at end of file
......@@ -6,4 +6,7 @@
<dimen name="dp_3">3dp</dimen>
<dimen name="dp_6">6dp</dimen>
<dimen name="dp_14">14dp</dimen>
<dimen name="dp_50">50dp</dimen>
<dimen name="dp_2">2dp</dimen>
<dimen name="dp_5">5dp</dimen>
</resources>
\ No newline at end of file
......@@ -12,5 +12,19 @@
<string name="my_list">My List</string>
<string name="rewards">Rewards</string>
<string name="continue_watching">Continue Watching</string>
<string name="male">Male</string>
<string name="female">FEMALE</string>
<string name="city">City</string>
<string name="suspense">Suspense</string>
<string name="modern">Modern</string>
<string name="ancient">Ancient</string>
<string name="military">Military</string>
<string name="fantasy">Fantasy</string>
<string name="blood">Blood</string>
<string name="history">History</string>
<string name="comedy">Comedy</string>
<string name="action">Action</string>
<string name="acg">ACG</string>
<string name="others">Others</string>
</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