首页UI 初步
This commit is contained in:
parent
f7d85a0869
commit
1adb1db7a2
|
|
@ -4,8 +4,8 @@ package com.remax.visualnovel.entity.response
|
||||||
* Created by HJW on 2025/8/14
|
* Created by HJW on 2025/8/14
|
||||||
*/
|
*/
|
||||||
data class Book(
|
data class Book(
|
||||||
val aiId: String,
|
val aiId: String = "",
|
||||||
val birthday: Long,
|
val birthday: Long = 0,
|
||||||
val characterName: String,
|
val characterName: String = "",
|
||||||
val headImg: String
|
val headImg: String = ""
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,13 @@ package com.remax.visualnovel.ui.main.book
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
|
import androidx.viewpager2.widget.ViewPager2
|
||||||
import com.alibaba.android.arouter.facade.annotation.Route
|
import com.alibaba.android.arouter.facade.annotation.Route
|
||||||
import com.alibaba.android.arouter.launcher.ARouter
|
import com.alibaba.android.arouter.launcher.ARouter
|
||||||
import com.dylanc.loadingstateview.BgColorType
|
import com.dylanc.loadingstateview.BgColorType
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
|
||||||
import com.remax.visualnovel.app.base.BaseBindingFragment
|
import com.remax.visualnovel.app.base.BaseBindingFragment
|
||||||
import com.remax.visualnovel.databinding.FragmentMainBookBinding
|
import com.remax.visualnovel.databinding.FragmentMainBookBinding
|
||||||
|
import com.remax.visualnovel.entity.response.Book
|
||||||
import com.remax.visualnovel.utils.Routers
|
import com.remax.visualnovel.utils.Routers
|
||||||
import com.remax.visualnovel.utils.StatusBarUtil3
|
import com.remax.visualnovel.utils.StatusBarUtil3
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
|
@ -22,18 +23,15 @@ class BookListFragment : BaseBindingFragment<FragmentMainBookBinding>() {
|
||||||
private val contactViewModel by viewModels<BookListViewModel>()
|
private val contactViewModel by viewModels<BookListViewModel>()
|
||||||
|
|
||||||
override fun onCreated(bundle: Bundle?) {
|
override fun onCreated(bundle: Bundle?) {
|
||||||
setUI()
|
initToolbar()
|
||||||
|
initViewPager()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun backgroundColorType(): BgColorType {
|
override fun backgroundColorType(): BgColorType {
|
||||||
return BgColorType.TRANSPARENT
|
return BgColorType.TRANSPARENT
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setUI() {
|
|
||||||
with (binding.toolbar) {
|
|
||||||
setPadding(paddingLeft, paddingTop + StatusBarUtil3.getStatusBarHeight(context), paddingRight, paddingBottom)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun newInstance(): BookListFragment {
|
fun newInstance(): BookListFragment {
|
||||||
|
|
@ -42,4 +40,36 @@ class BookListFragment : BaseBindingFragment<FragmentMainBookBinding>() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private fun initToolbar() {
|
||||||
|
with (binding.toolbar) {
|
||||||
|
setPadding(paddingLeft, paddingTop + StatusBarUtil3.getStatusBarHeight(context), paddingRight, paddingBottom)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initViewPager() {
|
||||||
|
with(binding.viewPager) {
|
||||||
|
orientation = ViewPager2.ORIENTATION_VERTICAL
|
||||||
|
offscreenPageLimit = 5
|
||||||
|
|
||||||
|
val bookList = listOf(
|
||||||
|
Book(characterName = "aaaaaa"),
|
||||||
|
Book(characterName = "是是是"),
|
||||||
|
Book(characterName = "顶顶顶顶"),
|
||||||
|
Book(characterName = "ffff"),
|
||||||
|
Book(characterName = "sssss"),
|
||||||
|
Book(characterName = "hhhhhh"),
|
||||||
|
Book(characterName = "eeeee"),
|
||||||
|
Book(characterName = "mmmmmmm"),
|
||||||
|
)
|
||||||
|
|
||||||
|
isUserInputEnabled = true
|
||||||
|
adapter = BookPagerAdapter().apply {
|
||||||
|
submitList(bookList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
package com.remax.visualnovel.ui.main.book
|
||||||
|
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.remax.visualnovel.entity.response.Book
|
||||||
|
import com.remax.visualnovel.ui.main.book.customui.BookItemView
|
||||||
|
|
||||||
|
|
||||||
|
class BookPagerAdapter : RecyclerView.Adapter<BookPagerAdapter.BookViewHolder>() {
|
||||||
|
|
||||||
|
private var books: List<Book> = emptyList()
|
||||||
|
private var onItemClickListener: ((Book) -> Unit)? = null
|
||||||
|
private var onBuyClickListener: ((Book) -> Unit)? = null
|
||||||
|
private var onFavoriteClickListener: ((Book) -> Unit)? = null
|
||||||
|
|
||||||
|
inner class BookViewHolder(private val bookItemView: BookItemView) :
|
||||||
|
RecyclerView.ViewHolder(bookItemView) {
|
||||||
|
|
||||||
|
fun bind(book: Book, position: Int) {
|
||||||
|
bookItemView.bind(book)
|
||||||
|
|
||||||
|
// 设置点击事件
|
||||||
|
/*bookItemView.onItemClickListener = onItemClickListener
|
||||||
|
bookItemView.onBuyClickListener = onBuyClickListener
|
||||||
|
bookItemView.onFavoriteClickListener = onFavoriteClickListener*/
|
||||||
|
|
||||||
|
// 可以根据位置设置不同的样式
|
||||||
|
when (position % 3) {
|
||||||
|
0 -> bookItemView.setBackgroundColor(Color.parseColor("#F0F8FF"))
|
||||||
|
1 -> bookItemView.setBackgroundColor(Color.parseColor("#FFF0F5"))
|
||||||
|
2 -> bookItemView.setBackgroundColor(Color.parseColor("#F0FFF0"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BookViewHolder {
|
||||||
|
val bookItemView = BookItemView(parent.context)
|
||||||
|
bookItemView.layoutParams = ViewGroup.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
|
)
|
||||||
|
return BookViewHolder(bookItemView)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: BookViewHolder, position: Int) {
|
||||||
|
val book = books[position]
|
||||||
|
holder.bind(book, position)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int = books.size
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置书籍数据
|
||||||
|
*/
|
||||||
|
fun submitList(newBooks: List<Book>) {
|
||||||
|
books = newBooks.toList()
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定位置的书籍
|
||||||
|
*/
|
||||||
|
fun getBookAt(position: Int): Book? {
|
||||||
|
return books.getOrNull(position)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置项目点击监听器
|
||||||
|
*/
|
||||||
|
fun setOnItemClickListener(listener: (Book) -> Unit) {
|
||||||
|
onItemClickListener = listener
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置购买点击监听器
|
||||||
|
*/
|
||||||
|
fun setOnBuyClickListener(listener: (Book) -> Unit) {
|
||||||
|
onBuyClickListener = listener
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置收藏点击监听器
|
||||||
|
*/
|
||||||
|
fun setOnFavoriteClickListener(listener: (Book) -> Unit) {
|
||||||
|
onFavoriteClickListener = listener
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.remax.visualnovel.ui.main.book.customui
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import com.remax.visualnovel.databinding.LayoutItemVpBooksBinding
|
||||||
|
import com.remax.visualnovel.entity.response.Book
|
||||||
|
|
||||||
|
class BookItemView @JvmOverloads constructor(
|
||||||
|
context: Context,
|
||||||
|
attrs: AttributeSet? = null,
|
||||||
|
defStyleAttr: Int = 0
|
||||||
|
) : LinearLayout(context, attrs, defStyleAttr) {
|
||||||
|
private val mBinding: LayoutItemVpBooksBinding =
|
||||||
|
LayoutItemVpBooksBinding.inflate(LayoutInflater.from(context), this, true)
|
||||||
|
|
||||||
|
|
||||||
|
init {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bind(book: Book) {
|
||||||
|
mBinding.tvTitle.text = book.characterName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ import android.os.Bundle
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||||
|
import androidx.viewpager2.widget.ViewPager2
|
||||||
import com.alibaba.android.arouter.facade.annotation.Route
|
import com.alibaba.android.arouter.facade.annotation.Route
|
||||||
import com.alibaba.android.arouter.launcher.ARouter
|
import com.alibaba.android.arouter.launcher.ARouter
|
||||||
import com.dylanc.loadingstateview.BgColorType
|
import com.dylanc.loadingstateview.BgColorType
|
||||||
|
|
@ -56,7 +57,7 @@ class HistoryFragment : BaseBindingFragment<FragmentMainHistoryBinding>() {
|
||||||
HistoryComicFragment.newInstance(),
|
HistoryComicFragment.newInstance(),
|
||||||
HistoryActorFragment.newInstance(),
|
HistoryActorFragment.newInstance(),
|
||||||
)
|
)
|
||||||
|
orientation = ViewPager2.ORIENTATION_HORIZONTAL
|
||||||
offscreenPageLimit = fragments.size
|
offscreenPageLimit = fragments.size
|
||||||
isUserInputEnabled = false
|
isUserInputEnabled = false
|
||||||
adapter = object : FragmentStateAdapter(this@HistoryFragment) {
|
adapter = object : FragmentStateAdapter(this@HistoryFragment) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle"
|
||||||
|
>
|
||||||
|
<size
|
||||||
|
android:width="260dp"
|
||||||
|
android:height="50dp"
|
||||||
|
/>
|
||||||
|
<corners android:radius="25dp" />
|
||||||
|
<gradient android:type="linear"
|
||||||
|
android:angle="0"
|
||||||
|
android:startColor="#ffa653ff"
|
||||||
|
android:endColor="#ff009dff"
|
||||||
|
/>
|
||||||
|
</shape>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 308 KiB |
|
|
@ -13,18 +13,11 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<com.remax.visualnovel.widget.uitoken.view.UITokenTextView
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
android:id="@+id/tvTitle"
|
android:id="@+id/view_pager"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="0dp"
|
||||||
android:layout_marginTop="100dp"
|
android:layout_weight="1"
|
||||||
android:gravity="center"
|
android:layout_marginHorizontal="@dimen/dp_10"
|
||||||
android:layout_marginStart="@dimen/nav_title_margin"
|
|
||||||
android:layout_marginEnd="@dimen/nav_title_margin"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:maxLines="1"
|
|
||||||
app:textColorToken="@string/color_txt_primary_normal"
|
|
||||||
app:textToken="@string/txt_title_m"
|
|
||||||
android:text="Books"
|
|
||||||
/>
|
/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
@ -0,0 +1,153 @@
|
||||||
|
<?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"
|
||||||
|
android:layout_marginTop="@dimen/dp_10">
|
||||||
|
|
||||||
|
<com.remax.visualnovel.widget.roundedimageview.RoundedImageView
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:src="@drawable/temp_book_bg"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
app:riv_corner_radius="@dimen/dp_25"
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<com.remax.visualnovel.widget.uitoken.view.UITokenRelativeLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
>
|
||||||
|
|
||||||
|
<com.remax.visualnovel.widget.uitoken.view.UITokenTextView
|
||||||
|
android:id="@+id/iv_score"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_margin="@dimen/dp_15"
|
||||||
|
android:textColor="@color/yellow_ffe"
|
||||||
|
android:textSize="@dimen/sp_20"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:drawableLeftCompat="@mipmap/score"
|
||||||
|
android:drawablePadding="@dimen/dp_10"
|
||||||
|
android:text="9.5"
|
||||||
|
/>
|
||||||
|
</com.remax.visualnovel.widget.uitoken.view.UITokenRelativeLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<com.remax.visualnovel.widget.uitoken.view.UITokenLinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_marginBottom="@dimen/dp_25"
|
||||||
|
android:layout_marginHorizontal="@dimen/dp_15">
|
||||||
|
<com.remax.visualnovel.widget.uitoken.view.UITokenTextView
|
||||||
|
android:id="@+id/tv_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="@dimen/sp_20"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:text="Lord of the Starry Sky Sword"
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
<com.remax.visualnovel.widget.uitoken.view.UITokenLinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<com.remax.visualnovel.widget.uitoken.view.UITokenTextView
|
||||||
|
android:id="@+id/iv_description"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginTop="@dimen/dp_10"
|
||||||
|
android:textColor="@color/white_alpha9"
|
||||||
|
android:textSize="@dimen/sp_16"
|
||||||
|
android:text="Once a prodigy, Lin Feng had his cultivation shattered and was cast out as trash. Just as hope was lost, he awakened an ancient mystical sword within his body. Now, he ..."
|
||||||
|
/>
|
||||||
|
|
||||||
|
<com.remax.visualnovel.widget.uitoken.view.UITokenImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@mipmap/icon_expand"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:layout_marginLeft="@dimen/dp_10"
|
||||||
|
/>
|
||||||
|
</com.remax.visualnovel.widget.uitoken.view.UITokenLinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<com.remax.visualnovel.widget.uitoken.view.UITokenLinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginTop="@dimen/dp_15"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<com.remax.visualnovel.widget.uitoken.view.UITokenLinearLayout
|
||||||
|
android:id="@+id/il_comments_num"
|
||||||
|
android:layout_width="@dimen/dp_50"
|
||||||
|
android:layout_height="@dimen/dp_50"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
app:advBgColor="@color/white_alphaaa"
|
||||||
|
app:advRadius="@dimen/dp_25" >
|
||||||
|
<com.remax.visualnovel.widget.uitoken.view.UITokenImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_margin="@dimen/dp_6"
|
||||||
|
android:textColor="@color/white_alpha9"
|
||||||
|
android:textSize="@dimen/sp_10"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:srcCompat="@mipmap/score"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<com.remax.visualnovel.widget.uitoken.view.UITokenTextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@color/white_alpha9"
|
||||||
|
android:textSize="@dimen/sp_10"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_marginTop="@dimen/dp_5"
|
||||||
|
android:text="1.2k"
|
||||||
|
/>
|
||||||
|
</com.remax.visualnovel.widget.uitoken.view.UITokenLinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<com.remax.visualnovel.widget.uitoken.view.UITokenFrameLayout
|
||||||
|
android:id="@+id/fl_readnow"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="@dimen/dp_50"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="@dimen/dp_10"
|
||||||
|
android:background="@drawable/bg_readnow"
|
||||||
|
>
|
||||||
|
<com.remax.visualnovel.widget.uitoken.view.UITokenTextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:textColor="@color/yellow_ffe"
|
||||||
|
android:textSize="@dimen/sp_20"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:drawableRightCompat="@mipmap/score"
|
||||||
|
android:drawablePadding="@dimen/dp_10"
|
||||||
|
android:text="@string/read_now"
|
||||||
|
/>
|
||||||
|
</com.remax.visualnovel.widget.uitoken.view.UITokenFrameLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</com.remax.visualnovel.widget.uitoken.view.UITokenLinearLayout>
|
||||||
|
|
||||||
|
</com.remax.visualnovel.widget.uitoken.view.UITokenLinearLayout>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 862 B |
Binary file not shown.
|
After Width: | Height: | Size: 850 B |
|
|
@ -224,12 +224,10 @@
|
||||||
<color name="setting_bubble_bg_color">#ff4d3e6b</color>
|
<color name="setting_bubble_bg_color">#ff4d3e6b</color>
|
||||||
<color name="setting_bubble_bg_selected_color">#ff312645</color>
|
<color name="setting_bubble_bg_selected_color">#ff312645</color>
|
||||||
<color name="cyan_73">#ff739ba7</color>
|
<color name="cyan_73">#ff739ba7</color>
|
||||||
|
<color name="yellow_ffe">#ffffe100</color>
|
||||||
|
<color name="white_alpha9">#99ffffff</color>
|
||||||
|
<color name="white_alpha1a">#1affffff</color>
|
||||||
|
<color name="white_alphaaa">#aaffffff</color>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -491,6 +491,7 @@
|
||||||
<string name="sure">SURE</string>
|
<string name="sure">SURE</string>
|
||||||
<string name="no">NO</string>
|
<string name="no">NO</string>
|
||||||
<string name="sort_by_date">Sort by Date</string>
|
<string name="sort_by_date">Sort by Date</string>
|
||||||
|
<string name="read_now">Read Now</string>
|
||||||
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
Loading…
Reference in New Issue