Commit 5244decb authored by jyx's avatar jyx

邀请页面UI样式开发

parent 81f8098b
......@@ -77,6 +77,11 @@
<activity
android:name=".ui.activitys.AwardActivity"
android:screenOrientation="portrait" />
<activity
android:name=".ui.activitys.SettingsActivity"
android:screenOrientation="portrait">
</activity>
<service
android:name=".service.UpdateService"
......@@ -126,7 +131,7 @@
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"
tools:replace="android:resource"/>
tools:replace="android:resource" />
</provider>
<!-- 一览 今⽇日头条sdk需添加 -->
......@@ -153,6 +158,7 @@
<service
android:name="com.qq.e.comm.DownloadService"
android:exported="false" />
<activity
android:name="com.qq.e.ads.ADActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize" />
......
......@@ -19,7 +19,7 @@ class MyPresenter : BasePresenter<MyView>() {
/**
* 获取签到内容
*/
open fun getSignInHomePageMsg(): Unit {
open fun getSignInHomePageMsg() {
// view.showLoading("加载中...");
AppHttpManager.getInstance(loanApplication)
.call(loanService.signInHomePageMsg,
......
......@@ -87,7 +87,7 @@ class LoginActivity : BaseActivity()
// 登录
mobile = mobile.replace(" ".toRegex(), "")
loginPresenter.login(mobile, code,ps)
loginPresenter.login(mobile, code, ps)
}
R.id.tvLoginAgreement -> {
......
package com.mints.goodmoney.ui.activitys
import android.os.Bundle
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import com.mints.goodmoney.R
import com.mints.goodmoney.common.Constant
import com.mints.goodmoney.manager.UserManager
import com.mints.goodmoney.ui.activitys.base.BaseActivity
import com.mints.goodmoney.ui.widgets.CustomDialogAsApple
import com.mints.goodmoney.ui.widgets.DialogListener
import com.mints.goodmoney.utils.CacheUtil
import kotlinx.android.synthetic.main.activity_settings.*
import kotlinx.android.synthetic.main.header_layout.*
class SettingsActivity : BaseActivity(), View.OnClickListener {
private var cdaa: CustomDialogAsApple? = null
private val userManager by lazy { UserManager.getInstance() }
override fun initViewsAndEvents() {
initLayout()
}
private fun initLayout() {
tv_title.text = "设置"
iv_left_icon.visibility = View.VISIBLE
iv_left_icon.setImageResource(R.mipmap.ic_arrow_back)
iv_left_icon.setOnClickListener(this)
item_phone.setOnClickListener(this)
item_wechat.setOnClickListener(this)
item_invitedCode.setOnClickListener(this)
item_cleanCache.setOnClickListener(this)
item_userAgree.setOnClickListener(this)
item_privacyAgree.setOnClickListener(this)
item_aboutUs.setOnClickListener(this)
btn_switch.setOnClickListener(this)
item_phone.findViewById<TextView>(R.id.tv_title).text = "手机号"
val phone = resources.getDrawable(R.mipmap.icon_settings_tel)
phone.setBounds(0, 0, 50, 50)
item_phone.findViewById<TextView>(R.id.tv_title).setCompoundDrawables(phone, null, null, null)
item_phone.findViewById<TextView>(R.id.tv_right).visibility = View.VISIBLE
item_phone.findViewById<ImageView>(R.id.iv_right).visibility = View.GONE
if (userManager.userIsLogin()) {
item_phone.findViewById<TextView>(R.id.tv_right).text = userManager.mobile
} else {
item_phone.findViewById<TextView>(R.id.tv_right).text = "未绑定"
}
item_wechat.findViewById<TextView>(R.id.tv_title).text = "微信号"
val wechat = resources.getDrawable(R.mipmap.icon_settings_wechat)
wechat.setBounds(0, 0, 50, 50)
item_wechat.findViewById<TextView>(R.id.tv_title).setCompoundDrawables(wechat, null, null, null)
item_wechat.findViewById<TextView>(R.id.tv_right).visibility = View.VISIBLE
item_wechat.findViewById<ImageView>(R.id.iv_right).visibility = View.GONE
item_wechat.findViewById<TextView>(R.id.tv_right).text = "未授权"
item_invitedCode.findViewById<TextView>(R.id.tv_title).text = "邀请码"
val invitedCode = resources.getDrawable(R.mipmap.icon_settings_invite)
invitedCode.setBounds(0, 0, 50, 50)
item_invitedCode.findViewById<TextView>(R.id.tv_title).setCompoundDrawables(invitedCode, null, null, null)
item_invitedCode.findViewById<TextView>(R.id.tv_right).visibility = View.VISIBLE
item_invitedCode.findViewById<ImageView>(R.id.iv_right).visibility = View.GONE
item_invitedCode.findViewById<TextView>(R.id.tv_right).text = "填写邀请码 海量金币等你拿"
item_cleanCache.findViewById<TextView>(R.id.tv_title).text = "清理缓存"
val cleanCache = resources.getDrawable(R.mipmap.icon_settings_clean)
cleanCache.setBounds(0, 0, 50, 50)
item_cleanCache.findViewById<TextView>(R.id.tv_title).setCompoundDrawables(cleanCache, null, null, null)
item_cleanCache.findViewById<TextView>(R.id.tv_right).visibility = View.VISIBLE
item_cleanCache.findViewById<ImageView>(R.id.iv_right).visibility = View.GONE
item_cleanCache.findViewById<TextView>(R.id.tv_right).text = CacheUtil.getTotalCacheSize(this)
item_userAgree.findViewById<TextView>(R.id.tv_title).text = "服务协议"
val userAgree = resources.getDrawable(R.mipmap.icon_settings_user)
userAgree.setBounds(0, 0, 50, 50)
item_userAgree.findViewById<TextView>(R.id.tv_title).setCompoundDrawables(userAgree, null, null, null)
item_userAgree.findViewById<TextView>(R.id.tv_right).visibility = View.GONE
item_userAgree.findViewById<ImageView>(R.id.iv_right).visibility = View.VISIBLE
item_privacyAgree.findViewById<TextView>(R.id.tv_title).text = "隐私协议"
val privacyAgree = resources.getDrawable(R.mipmap.icon_settings_privacy)
privacyAgree.setBounds(0, 0, 50, 50)
item_privacyAgree.findViewById<TextView>(R.id.tv_title).setCompoundDrawables(privacyAgree, null, null, null)
item_privacyAgree.findViewById<TextView>(R.id.tv_right).visibility = View.GONE
item_privacyAgree.findViewById<ImageView>(R.id.iv_right).visibility = View.VISIBLE
item_aboutUs.findViewById<TextView>(R.id.tv_title).text = "关于我们"
val aboutUs = resources.getDrawable(R.mipmap.icon_settings_about)
aboutUs.setBounds(0, 0, 50, 50)
item_aboutUs.findViewById<TextView>(R.id.tv_title).setCompoundDrawables(aboutUs, null, null, null)
item_aboutUs.findViewById<TextView>(R.id.tv_right).visibility = View.GONE
item_aboutUs.findViewById<ImageView>(R.id.iv_right).visibility = View.VISIBLE
}
override fun getContentViewLayoutID() = R.layout.activity_settings
override fun isApplyKitKatTranslucency() = false
override fun onClick(v: View?) {
when (v?.id) {
R.id.item_phone -> {
if (!userManager.userIsLogin()) {
readyGo(LoginActivity::class.java)
}
}
R.id.item_wechat -> {
if (!userManager.userIsLogin()) {
readyGo(LoginActivity::class.java)
}
}
R.id.item_invitedCode -> {
}
R.id.item_cleanCache -> {
clearDialog()
}
R.id.item_userAgree -> {
val bundle = Bundle()
bundle.putString(WebActivity.WEB_TITLE, getString(R.string.members_name))
bundle.putString(WebActivity.WEB_URL, Constant.MEMBERS_URL)
readyGo(WebActivity::class.java, bundle)
}
R.id.item_privacyAgree -> {
val bundle = Bundle()
bundle.putString(WebActivity.WEB_TITLE, getString(R.string.privacy_name))
bundle.putString(WebActivity.WEB_URL, Constant.PRIVACY_URL)
readyGo(WebActivity::class.java, bundle)
}
R.id.item_aboutUs -> {
}
R.id.btn_switch -> {
}
R.id.iv_left_icon -> {
onBackPressed()
}
}
}
private fun submitInvitedCode() {
cdaa = CustomDialogAsApple(context, object : DialogListener() {
override fun onClick(v: View) {
when (v.id) {
R.id.dialog_btn_right -> {
}
}
cdaa?.dismiss()
cdaa = null
}
})
cdaa?.let {
it.setContent("提交邀请码")
it.setLeft("取消")
it.setRight("确认")
it.show()
}
}
private fun clearDialog() {
cdaa = CustomDialogAsApple(context, object : DialogListener() {
override fun onClick(v: View) {
when (v.id) {
R.id.dialog_btn_right ->
try {
CacheUtil.clearAllCache(context)
item_cleanCache.findViewById<TextView>(R.id.tv_right).text = "0KB"
} catch (e: Exception) {
e.printStackTrace()
}
}
cdaa?.dismiss()
}
})
cdaa?.let {
it.setContent("确定清除缓存吗?")
it.setLeft("取消")
it.setRight("清除")
it.show()
}
}
}
\ No newline at end of file
package com.mints.goodmoney.ui.adapter
import android.content.Context
import android.view.View
import com.mints.goodmoney.R
class BannerTaskAdapter(context: Context) : BannerBaseAdapter<Any>(context) {
override fun getLayoutResID() = R.layout.item_bv_friends_task
override fun convert(convertView: View?, data: Any?) {
}
}
\ No newline at end of file
package com.mints.goodmoney.ui.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.mints.goodmoney.R
class InvitedAdapter(private val invitedData: List<Any>) : RecyclerView.Adapter<InvitedAdapter.InvitedHolder>() {
private var mOnItemClickListener: OnItemClickListener? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): InvitedHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_recy_invited, parent, false)
return InvitedHolder(view)
}
override fun getItemCount() = invitedData.size
override fun onBindViewHolder(holder: InvitedHolder, position: Int) {
holder.itemView.setOnClickListener {
mOnItemClickListener?.onItemClick(holder.itemView, position)
}
}
inner class InvitedHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val tvNum = itemView.findViewById<TextView>(R.id.item_invited_tv_num)
private val iv = itemView.findViewById<TextView>(R.id.item_invited_iv)
private val tvName = itemView.findViewById<TextView>(R.id.item_invited_tv_name)
private val tvCoin = itemView.findViewById<TextView>(R.id.item_invited_tv_coin)
}
//define interface
interface OnItemClickListener {
fun onItemClick(view: View?, position: Int)
}
fun setOnItemClickListener(listener: OnItemClickListener) {
mOnItemClickListener = listener
}
}
\ No newline at end of file
......@@ -70,7 +70,9 @@ class MainMyAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder> {
holder.itemTaskTitle.text = taskBean.title
holder.itemTaskInfo.text = taskBean.info
holder.itemTaskMoney.text = taskBean.coin
holder.itemTaskMoney.setCompoundDrawables(mContext.resources.getDrawable(R.mipmap.ic_gold), null, null, null)
val gold = mContext.resources.getDrawable(R.mipmap.ic_gold)
gold.setBounds(0, 0, 50, 50)
holder.itemTaskMoney.setCompoundDrawables(gold, null, null, null)
holder.itemTaskImg.setImageDrawable(mContext.resources.getDrawable(taskBean.imageSrc))
if (taskBean.btnStr.isNotEmpty() && !taskBean.needTimer) {
holder.itemTaskClick.text = taskBean.btnStr
......
package com.mints.goodmoney.ui.fragment
import android.text.TextUtils
import android.view.View
import android.widget.TextView
import androidx.recyclerview.widget.DividerItemDecoration
import com.mints.goodmoney.R
import com.mints.goodmoney.common.AppConfig
import com.mints.goodmoney.common.Constant
import com.mints.goodmoney.manager.UserManager
import com.mints.goodmoney.mvp.presenters.PanPresenter
import com.mints.goodmoney.mvp.views.PanView
import com.mints.goodmoney.mvp.model.BannerBean
import com.mints.goodmoney.ui.adapter.BannerAdapter
import com.mints.goodmoney.ui.adapter.BannerBaseAdapter
import com.mints.goodmoney.ui.adapter.BannerTaskAdapter
import com.mints.goodmoney.ui.adapter.InvitedAdapter
import com.mints.goodmoney.ui.fragment.base.BaseFragment
import com.mints.goodmoney.ui.widgets.tablayout.TabLayout
import kotlinx.android.synthetic.main.fragment_main_friends.*
import kotlinx.android.synthetic.main.header_layout.*
/**
* 描述:邀请好友
......@@ -16,13 +25,109 @@ import com.mints.goodmoney.ui.fragment.base.BaseFragment
*/
class FriendsFragment : BaseFragment() {
private val TAG = FriendsFragment::class.java.simpleName
private val userManager by lazy { UserManager.getInstance() }
private var bvTaskData: List<Any> = arrayListOf()
private var bvBannerData: List<BannerBean.ListBean> = arrayListOf()
private var invitedData: List<Any> = arrayListOf()
override fun getContentViewLayoutID() = R.layout.fragment_main_friends
override fun initViewsAndEvents() {
initView()
initRecy()
initBanner()
}
private fun initView() {
tv_title.text = "邀请好友"
view_title1.findViewById<TextView>(R.id.view_title).text = "邀好友 做任务 赚现金"
view_title2.findViewById<TextView>(R.id.view_title).text = "邀好友 赚分红 邀越多 赚越多"
}
private fun initRecy() {
// rg.setOnCheckedChangeListener { group, checkedId ->
// when (checkedId) {
// R.id.rb_my_friends -> {
// showToast("我的好友")
// }
// R.id.rb_world_person -> {
// showToast("世界人民")
// }
// }
//
// }
tab_friends.addTab(tab_friends.newTab().setText("我的好友").setTag("my_friends"))
tab_friends.addTab(tab_friends.newTab().setText("世界人民").setTag("world_person"))
tab_friends.setOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabReselected(tab: TabLayout.Tab?) {
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
}
override fun onTabSelected(tab: TabLayout.Tab?) {
tab?.let {
if (it.tag == "我的好友") {
showToast("我的好友")
} else {
showToast("世界人民")
}
}
}
})
// tab_friends.setOnScrollChangeListener(object :.(){})
recy_friends.addItemDecoration(DividerItemDecoration(mContext, DividerItemDecoration.VERTICAL))
val invitedAdapter = InvitedAdapter(invitedData)
recy_friends.adapter = invitedAdapter
invitedAdapter.setOnItemClickListener(object : InvitedAdapter.OnItemClickListener {
override fun onItemClick(view: View?, position: Int) {
}
})
}
private fun initBanner() {
val bannerTaskAdapter = BannerTaskAdapter(mContext)
bannerTaskAdapter.setData(bvTaskData)
bv_friends_task.setAdapter(bannerTaskAdapter)
bannerTaskAdapter.setOnPageTouchListener(object : BannerBaseAdapter.OnPageTouchListener<Any> {
override fun onPageClick(position: Int, t: Any?) {
}
override fun onPageDown() {
bv_friends_task.stopAutoScroll()
}
override fun onPageUp() {
bv_friends_task.startAutoScroll()
}
})
val bannerAdapter = BannerAdapter(mContext)
bannerAdapter.setData(bvBannerData)
bv_friends_banner.setAdapter(bannerAdapter)
bannerAdapter.setOnPageTouchListener(object : BannerBaseAdapter.OnPageTouchListener<BannerBean.ListBean> {
override fun onPageClick(position: Int, t: BannerBean.ListBean?) {
}
override fun onPageDown() {
bv_friends_task.stopAutoScroll()
}
override fun onPageUp() {
bv_friends_task.startAutoScroll()
}
})
}
override fun onHiddenChanged(hidden: Boolean) {
......@@ -36,12 +141,21 @@ class FriendsFragment : BaseFragment() {
override fun onResume() {
super.onResume()
if (AppConfig.fragmentClickFlag === Constant.FRAGMENT_CLICK_FRIENDS) {
if (AppConfig.fragmentClickFlag == Constant.FRAGMENT_CLICK_FRIENDS) {
if (!TextUtils.isEmpty(userManager?.userID)) {
} else {
}
}
bv_friends_banner.startAutoScroll()
bv_friends_task.stopAutoScroll()
}
override fun onPause() {
super.onPause()
bv_friends_banner.startAutoScroll()
bv_friends_task.stopAutoScroll()
}
override fun onDestroy() {
......
package com.mints.goodmoney.ui.fragment
import android.Manifest
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.text.TextUtils
import android.view.View
import android.widget.AdapterView
import androidx.recyclerview.widget.DividerItemDecoration
import com.google.gson.Gson
import com.mints.goodmoney.BuildConfig
import com.mints.goodmoney.R
import com.mints.goodmoney.common.AppConfig
import com.mints.goodmoney.common.Constant
......@@ -13,6 +17,8 @@ import com.mints.goodmoney.manager.UserManager
import com.mints.goodmoney.mvp.model.*
import com.mints.goodmoney.mvp.presenters.MyPresenter
import com.mints.goodmoney.mvp.views.MyView
import com.mints.goodmoney.ui.activitys.LoginActivity
import com.mints.goodmoney.ui.activitys.SettingsActivity
import com.mints.goodmoney.ui.adapter.GvMyAdapter
import com.mints.goodmoney.ui.adapter.MainMyAdapter
import com.mints.goodmoney.ui.fragment.base.BaseFragment
......@@ -20,17 +26,21 @@ import com.mints.goodmoney.utils.AppPackageUsageUtils
import com.mints.goodmoney.utils.SpanUtils
import com.mints.library.net.netstatus.NetUtils
import com.mints.library.utils.ConstantUtil
import com.mints.library.utils.GlideUtils
import com.mints.library.utils.nodoubleclick.AntiShake
import com.scwang.smartrefresh.layout.api.RefreshLayout
import com.scwang.smartrefresh.layout.listener.OnRefreshListener
import com.tbruyelle.rxpermissions.RxPermissions
import kotlinx.android.synthetic.main.fragment_main_my.*
import kotlinx.android.synthetic.main.header_layout.*
import kotlinx.android.synthetic.main.item_fragment_main_my_bottom.*
import kotlinx.android.synthetic.main.item_fragment_main_my_clock.*
import kotlinx.android.synthetic.main.item_fragment_main_my_promotions.*
import kotlinx.android.synthetic.main.item_fragment_main_my_title.*
import java.util.*
import kotlinx.android.synthetic.main.view_title.*
import net.grandcentrix.tray.AppPreferences
import java.math.BigDecimal
import java.util.*
/**
* 描述:我
......@@ -131,15 +141,22 @@ class MyFragment : BaseFragment(), MyView, MainMyAdapter.OnItemChildClickListene
"}"
private fun initView() {
item_title_login.setOnClickListener(this)
item_title_settings.setOnClickListener(this)
item_title_gold.setOnClickListener(this)
item_title_cash.setOnClickListener(this)
iv_right_icon.visibility = View.VISIBLE
iv_right_icon.setImageResource(R.mipmap.ic_my_account)
tv_title.text = "个人中心"
item_iv_settings.setOnClickListener(this)
item_title_id.setOnClickListener(this)
iv_right_icon.setOnClickListener(this)
btn_withdraw.setOnClickListener(this)
item_title_invitecode.setOnClickListener(this)
item_title_invitecode_copy.setOnClickListener(this)
ll_my_login.setOnClickListener(this)
item_promotions_egv.onItemClickListener = this
view_title.text = "每日任务"
item_promotions_egv.onItemClickListener = this
item_bottom_version.text = "v" + ConstantUtil.getVersionName(mContext)
}
......@@ -175,12 +192,13 @@ class MyFragment : BaseFragment(), MyView, MainMyAdapter.OnItemChildClickListene
override fun onResume() {
super.onResume()
if (AppConfig.fragmentClickFlag == Constant.FRAGMENT_CLICK_MY) {
if (!TextUtils.isEmpty(userManager?.userID)) {
if (!TextUtils.isEmpty(userManager.userID)) {
myPresenter.getUserTaskMsg(false)
} else {
// 游戏登录
myPresenter.userLogin(ps)
// 游客登录
myPresenter.userLogin(ps)
}
}
}
......@@ -204,26 +222,26 @@ class MyFragment : BaseFragment(), MyView, MainMyAdapter.OnItemChildClickListene
}
userConfig = data
// setUserLoginStatus()
setUserLoginStatus()
}
override fun getUserTaskMsgFail() {
if (srl_my != null) srl_my.finishRefresh(false)
userConfig = null
ll_my_hot.visibility = View.GONE
// setUserLoginStatus()
item_promotions_egv.visibility = View.GONE
setUserLoginStatus()
}
override fun getMyHotActivitySuc(data: BannerBean?) {
if (UserManager.getInstance().adShowFlag) {
data?.let {
ll_my_hot.visibility = View.VISIBLE
item_promotions_egv.visibility = View.VISIBLE
hotList = it.list
item_promotions_egv.adapter = GvMyAdapter(mContext, hotList)
}
} else {
ll_my_hot.visibility = View.GONE
item_promotions_egv.visibility = View.GONE
}
}
......@@ -232,6 +250,7 @@ class MyFragment : BaseFragment(), MyView, MainMyAdapter.OnItemChildClickListene
signCardBean = null
return
}
signCardBean = signBean
// 初始化签到
setSignDayLayout(signCardBean!!)
......@@ -266,8 +285,7 @@ class MyFragment : BaseFragment(), MyView, MainMyAdapter.OnItemChildClickListene
* @param signCardBean
*/
private fun setSignDayLayout(signCardBean: SignCardBean) {
item_clock_signview.visibility = View.VISIBLE
item_clock_sign.visibility = View.VISIBLE
ll_my_sign.visibility = View.VISIBLE
val nowDate = signCardBean.nowDate
var signStatus = 0 //0-未签到 1-已签到 2-已签到且看了视频
val signList = signCardBean.list
......@@ -352,50 +370,52 @@ class MyFragment : BaseFragment(), MyView, MainMyAdapter.OnItemChildClickListene
}
}
// private fun setUserLoginStatus() {
// if (userManager.userIsLogin()) {
// // 已登录
// if (!TextUtils.isEmpty(userManager.getWxOpenid())) {
// GlideUtils.loadImageView(context, userManager.getWxHeader(), icMyHead)
// item_title_id.setText(userManager.getWxName())
// } else {
// var mobile = userManager.mobile
// if (!TextUtils.isEmpty(mobile)) {
// mobile = mobile.substring(0, 3) + "****" + mobile.substring(mobile.length - 4, mobile.length)
// }
// item_title_id.text = "手机:$mobile"
// item_title_avatar.setImageResource(R.mipmap.ic_my)
// }
private fun setUserLoginStatus() {
if (userManager.userIsLogin()) {
// 已登录
if (!TextUtils.isEmpty(userManager.getWxOpenid())) {
GlideUtils.loadImageView(context, userManager.getWxHeader(), item_title_avatar)
item_title_id.setText(userManager.getWxName())
} else {
var mobile = userManager.mobile
if (!TextUtils.isEmpty(mobile)) {
mobile = mobile.substring(0, 3) + "****" + mobile.substring(mobile.length - 4, mobile.length)
}
item_title_id.text = "手机:$mobile"
item_title_avatar.setImageResource(R.mipmap.ic_my)
}
// item_title_login.setVisibility(View.GONE)
// } else {
// // 未登录
// var userId = userManager.userID
// if (!TextUtils.isEmpty(userId) && userId.length > 11) {
// userId = userId.substring(userId.length - 10)
// item_title_id.text = "游客$userId 去登录"
// } else {
// item_title_id.text = "游客 去登录"
// }
} else {
// 未登录
var userId = userManager.userID
if (!TextUtils.isEmpty(userId) && userId.length > 11) {
userId = userId.substring(userId.length - 10)
item_title_id.text = "游客$userId 去登录"
} else {
item_title_id.text = "游客 去登录"
}
// item_title_login.visibility = View.VISIBLE
// item_title_avatar.setImageResource(R.mipmap.ic_my)
// }
// if (BuildConfig.DEBUG) {
// item_title_id.text = "测试环境->" + item_title_id.text.toString()
// }
// val userGold: String
// val usercash: String
// if (userConfig == null) {
// userGold = "0.00"
// usercash = "0.00"
// } else {
// userGold = java.lang.String.valueOf(userConfig!!.coin)
// val allcoinBig = BigDecimal(userGold)
// val rateBig = BigDecimal("10000")
// usercash = allcoinBig.divide(rateBig).setScale(2, BigDecimal.ROUND_DOWN).toString()
// }
// item_title_gold_count.text = userGold
item_title_avatar.setImageResource(R.mipmap.ic_my)
}
if (BuildConfig.DEBUG) {
item_title_id.text = "测试环境->" + item_title_id.text.toString()
}
val userGold: String
val usercash: String
if (userConfig == null) {
userGold = "0.00"
usercash = "0.00"
} else {
userGold = java.lang.String.valueOf(userConfig!!.coin)
val allcoinBig = BigDecimal(userGold)
val rateBig = BigDecimal("10000")
usercash = allcoinBig.divide(rateBig).setScale(2, BigDecimal.ROUND_DOWN).toString()
}
// 零钱金币
item_title_gold_count.text = userGold
// item_title_cash_count.text = usercash
// }
}
/**
* 处理列表数据
......@@ -476,25 +496,6 @@ class MyFragment : BaseFragment(), MyView, MainMyAdapter.OnItemChildClickListene
R.mipmap.ic_launcher, "分享到微信群提高到300%", shareStr)
dataList.add(shareTask)
//积分兑换
// if (data.isMobileCoinExchangeEnable) {
// llVersusExchange.setVisibility(View.VISIBLE)
// viewVersusExchange.setVisibility(View.VISIBLE)
// tvVersusExchangeGold.setText("+" + data.mobileCoinExchangeCompleteReward)
// val exchangeTask = TaskBean(R.mipmap.ic_launcher, "喝水达标($watercompleteComplatecount/$challengeWatercompleteMaxcount)", "" + userConfig.challenge_watercomplete_coin,
// R.mipmap.ic_launcher, "每日喝水达标即可领取", waterStr)
//
// if (data.mobileCoinExchangeStatus === 0) {
// tvVersusExchange.setText("去完成")
// tvVersusExchange.setBackground(resources.getDrawable(R.drawable.shape_main_water))
// } else {
// tvVersusExchange.setText("立即领取")
// tvVersusExchange.setBackground(resources.getDrawable(R.drawable.shape_tv_gold))
// }
//
// dataList[6] = shareTask
// }
//绑定微信号 Complete 0-未完成 1-完成 2-领取
val challengeWechatComplete = data.challenge_wechat_complete
if (challengeWechatComplete == 0) {
......@@ -726,51 +727,47 @@ class MyFragment : BaseFragment(), MyView, MainMyAdapter.OnItemChildClickListene
}
when (v?.id) {
R.id.item_title_login -> {
// if (!userManager.userIsLogin()) {
// readyGo(WxLoginActivity::class.java)
// }
R.id.ll_my_login -> {
if (!userManager.userIsLogin()) {
readyGo(LoginActivity::class.java)
}
}
R.id.item_title_settings -> {
// readyGo(SettingActivity::class.java)
R.id.item_title_id -> {
if (!userManager.userIsLogin()) {
readyGo(LoginActivity::class.java)
}
}
R.id.item_title_gold -> {
// if (userConfig == null) {
// showToast("网络异常,请检测网络!")
// myPresenter.getUserTaskMsg(false)
// return
// }
//
// readyGo(GoldTryActivity::class.java)
R.id.item_iv_settings -> {
readyGo(SettingsActivity::class.java)
}
R.id.item_title_cash -> {
// if (userConfig == null) {
// showToast("网络异常,请检测网络!")
// myPresenter.getUserTaskMsg(false)
// return
// }
//
// readyGo(DrawcashActivity::class.java)
R.id.btn_withdraw -> {
if (userConfig == null) {
showToast("网络异常,请检测网络!")
myPresenter.getUserTaskMsg(false)
return
}
// readyGo(GoldTryActivity::class.java)
}
R.id.item_title_invitecode -> {
// if (userConfig != null) {
// val invitedCode = userConfig!!.idcode
// if (!TextUtils.isEmpty(invitedCode)) {
// showToast("复制成功")
// val clipboardManager = context!!.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
// clipboardManager.setPrimaryClip(ClipData.newPlainText("invitecode_copy", invitedCode))
// }
// }
if (userConfig != null) {
val invitedCode = userConfig!!.idcode
if (!TextUtils.isEmpty(invitedCode)) {
showToast("复制成功")
val clipboardManager = mContext.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
clipboardManager.setPrimaryClip(ClipData.newPlainText("invitecode_copy", invitedCode))
}
}
}
R.id.item_title_invitecode_copy -> {
// if (userConfig != null) {
// val invitedCode = userConfig!!.idcode
// if (!TextUtils.isEmpty(invitedCode)) {
// showToast("复制成功")
// val clipboardManager = context!!.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
// clipboardManager.setPrimaryClip(ClipData.newPlainText("invitecode_copy", invitedCode))
// }
// }
if (userConfig != null) {
val invitedCode = userConfig!!.idcode
if (!TextUtils.isEmpty(invitedCode)) {
showToast("复制成功")
val clipboardManager = mContext.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
clipboardManager.setPrimaryClip(ClipData.newPlainText("invitecode_copy", invitedCode))
}
}
}
else -> {
}
......
package com.mints.goodmoney.ui.widgets;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.appbar.AppBarLayout;
public final class FlingBehavior extends AppBarLayout.Behavior {
private static final int TOP_CHILD_FLING_THRESHOLD = 3;
private boolean isPositive;
public FlingBehavior() {
}
public FlingBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onNestedFling(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY, boolean consumed) {
if (velocityY > 0 && !isPositive || velocityY < 0 && isPositive) {
velocityY = velocityY * -1;
}
if (target instanceof RecyclerView && velocityY < 0) {
final RecyclerView recyclerView = (RecyclerView) target;
final View firstChild = recyclerView.getChildAt(0);
final int childAdapterPosition = recyclerView.getChildAdapterPosition(firstChild);
consumed = childAdapterPosition > TOP_CHILD_FLING_THRESHOLD;
}
return super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed);
}
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
isPositive = dy > 0;
}
}
\ No newline at end of file
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mints.goodmoney.ui.widgets.tablayout;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import androidx.interpolator.view.animation.FastOutLinearInInterpolator;
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
import androidx.interpolator.view.animation.LinearOutSlowInInterpolator;
class AnimationUtils {
static final Interpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
static final Interpolator FAST_OUT_SLOW_IN_INTERPOLATOR = new FastOutSlowInInterpolator();
static final Interpolator FAST_OUT_LINEAR_IN_INTERPOLATOR = new FastOutLinearInInterpolator();
static final Interpolator LINEAR_OUT_SLOW_IN_INTERPOLATOR = new LinearOutSlowInInterpolator();
static final Interpolator DECELERATE_INTERPOLATOR = new DecelerateInterpolator();
/**
* Linear interpolation between {@code startValue} and {@code endValue} by {@code fraction}.
*/
static float lerp(float startValue, float endValue, float fraction) {
return startValue + (fraction * (endValue - startValue));
}
static int lerp(int startValue, int endValue, float fraction) {
return startValue + Math.round(fraction * (endValue - startValue));
}
static class AnimationListenerAdapter implements Animation.AnimationListener {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
}
}
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mints.goodmoney.ui.widgets.tablayout;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import com.mints.goodmoney.R;
/**
* TabItem is a special 'view' which allows you to declare tab items for a {@link TabLayout}
* within a layout. This view is not actually added to TabLayout, it is just a dummy which allows
* setting of a tab items's text, icon and custom layout. See TabLayout for more information on how
* to use it.
*
* @attr ref android.support.design.R.styleable#TabItem_android_icon
* @attr ref android.support.design.R.styleable#TabItem_android_text
* @attr ref android.support.design.R.styleable#TabItem_android_layout
*
* @see TabLayout
*/
public final class TabItem extends View {
final CharSequence mText;
final Drawable mIcon;
final int mCustomLayout;
public TabItem(Context context) {
this(context, null);
}
public TabItem(Context context, AttributeSet attrs) {
super(context, attrs);
final TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.TabItem);
mText = a.getText(R.styleable.TabItem_android_text);
mIcon = a.getDrawable(R.styleable.TabItem_android_icon);
mCustomLayout = a.getResourceId(R.styleable.TabItem_android_layout, 0);
a.recycle();
}
}
\ No newline at end of file
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mints.goodmoney.ui.widgets.tablayout;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.database.DataSetObserver;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.Layout;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.IntDef;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Px;
import androidx.annotation.RestrictTo;
import androidx.annotation.StringRes;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.appcompat.widget.TooltipCompat;
import androidx.core.util.Pools;
import androidx.core.view.GravityCompat;
import androidx.core.view.PointerIconCompat;
import androidx.core.view.ViewCompat;
import androidx.core.widget.TextViewCompat;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.google.android.material.animation.AnimationUtils;
import com.mints.goodmoney.R;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
import static androidx.viewpager.widget.ViewPager.SCROLL_STATE_DRAGGING;
import static androidx.viewpager.widget.ViewPager.SCROLL_STATE_IDLE;
import static androidx.viewpager.widget.ViewPager.SCROLL_STATE_SETTLING;
/**
* TabLayout provides a horizontal layout to display tabs.
*
* <p>Population of the tabs to display is
* done through {@link Tab} instances. You create tabs via {@link #newTab()}. From there you can
* change the tab's label or icon via {@link Tab#setText(int)} and {@link Tab#setIcon(int)}
* respectively. To display the tab, you need to add it to the layout via one of the
* {@link #addTab(Tab)} methods. For example:
* <pre>
* TabLayout tabLayout = ...;
* tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
* tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
* tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
* </pre>
* You should set a listener via {@link #setOnTabSelectedListener(OnTabSelectedListener)} to be
* notified when any tab's selection state has been changed.
*
* <p>You can also add items to TabLayout in your layout through the use of {@link TabItem}.
* An example usage is like so:</p>
*
* <pre>
* &lt;android.support.design.widget.TabLayout
* android:layout_height=&quot;wrap_content&quot;
* android:layout_width=&quot;match_parent&quot;&gt;
*
* &lt;android.support.design.widget.TabItem
* android:text=&quot;@string/tab_text&quot;/&gt;
*
* &lt;android.support.design.widget.TabItem
* android:icon=&quot;@drawable/ic_android&quot;/&gt;
*
* &lt;/android.support.design.widget.TabLayout&gt;
* </pre>
*
* <h3>ViewPager integration</h3>
* <p>
* If you're using a {@link androidx.viewpager} together
* with this layout, you can call {@link #setupWithViewPager(ViewPager)} to link the two together.
* This layout will be automatically populated from the {@link PagerAdapter}'s page titles.</p>
*
* <p>
* This view also supports being used as part of a ViewPager's decor, and can be added
* directly to the ViewPager in a layout resource file like so:</p>
*
* <pre>
* &lt;android.support.v4.view.ViewPager
* android:layout_width=&quot;match_parent&quot;
* android:layout_height=&quot;match_parent&quot;&gt;
*
* &lt;android.support.design.widget.TabLayout
* android:layout_width=&quot;match_parent&quot;
* android:layout_height=&quot;wrap_content&quot;
* android:layout_gravity=&quot;top&quot; /&gt;
*
* &lt;/android.support.v4.view.ViewPager&gt;
* </pre>
*
* @attr ref android.support.design.R.styleable#TabLayout_tabPadding
* @attr ref android.support.design.R.styleable#TabLayout_tabPaddingStart
* @attr ref android.support.design.R.styleable#TabLayout_tabPaddingTop
* @attr ref android.support.design.R.styleable#TabLayout_tabPaddingEnd
* @attr ref android.support.design.R.styleable#TabLayout_tabPaddingBottom
* @attr ref android.support.design.R.styleable#TabLayout_tabContentStart
* @attr ref android.support.design.R.styleable#TabLayout_tabBackground
* @attr ref android.support.design.R.styleable#TabLayout_tabMinWidth
* @attr ref android.support.design.R.styleable#TabLayout_tabMaxWidth
* @attr ref android.support.design.R.styleable#TabLayout_tabTextAppearance
* @see <a href="http://www.google.com/design/spec/components/tabs.html">Tabs</a>
*/
@ViewPager.DecorView
public class TabLayout extends HorizontalScrollView {
private static final int DEFAULT_HEIGHT_WITH_TEXT_ICON = 72; // dps
static final int DEFAULT_GAP_TEXT_ICON = 8; // dps
private static final int INVALID_WIDTH = -1;
private static final int DEFAULT_HEIGHT = 48; // dps
private static final int TAB_MIN_WIDTH_MARGIN = 56; //dps
static final int FIXED_WRAP_GUTTER_MIN = 16; //dps
static final int MOTION_NON_ADJACENT_OFFSET = 24;
private static final int ANIMATION_DURATION = 300;
private static final Pools.Pool<Tab> sTabPool = new Pools.SynchronizedPool<>(16);
/**
* Scrollable tabs display a subset of tabs at any given moment, and can contain longer tab
* labels and a larger number of tabs. They are best used for browsing contexts in touch
* interfaces when users don’t need to directly compare the tab labels.
*
* @see #setTabMode(int)
* @see #getTabMode()
*/
public static final int MODE_SCROLLABLE = 0;
/**
* Fixed tabs display all tabs concurrently and are best used with content that benefits from
* quick pivots between tabs. The maximum number of tabs is limited by the view’s width.
* Fixed tabs have equal width, based on the widest tab label.
*
* @see #setTabMode(int)
* @see #getTabMode()
*/
public static final int MODE_FIXED = 1;
/**
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
@IntDef(value = {MODE_SCROLLABLE, MODE_FIXED})
@Retention(RetentionPolicy.SOURCE)
public @interface Mode {
}
/**
* Gravity used to fill the {@link TabLayout} as much as possible. This option only takes effect
* when used with {@link #MODE_FIXED}.
*
* @see #setTabGravity(int)
* @see #getTabGravity()
*/
public static final int GRAVITY_FILL = 0;
/**
* Gravity used to lay out the tabs in the center of the {@link TabLayout}.
*
* @see #setTabGravity(int)
* @see #getTabGravity()
*/
public static final int GRAVITY_CENTER = 1;
/**
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
@IntDef(flag = true, value = {GRAVITY_FILL, GRAVITY_CENTER})
@Retention(RetentionPolicy.SOURCE)
public @interface TabGravity {
}
/**
* Callback interface invoked when a tab's selection state changes.
*/
public interface OnTabSelectedListener {
/**
* Called when a tab enters the selected state.
*
* @param tab The tab that was selected
*/
public void onTabSelected(Tab tab);
/**
* Called when a tab exits the selected state.
*
* @param tab The tab that was unselected
*/
public void onTabUnselected(Tab tab);
/**
* Called when a tab that is already selected is chosen again by the user. Some applications
* may use this action to return to the top level of a category.
*
* @param tab The tab that was reselected.
*/
public void onTabReselected(Tab tab);
}
private final ArrayList<Tab> mTabs = new ArrayList<>();
private Tab mSelectedTab;
private final SlidingTabStrip mTabStrip;
int mTabPaddingStart;
int mTabPaddingTop;
int mTabPaddingEnd;
int mTabPaddingBottom;
int mTabTextAppearance;
ColorStateList mTabTextColors;
float mTabTextSize;
float mTabTextMultiLineSize;
final int mTabBackgroundResId;
int mTabMaxWidth = Integer.MAX_VALUE;
private final int mRequestedTabMinWidth;
private final int mRequestedTabMaxWidth;
private final int mScrollableTabMinWidth;
private int mContentInsetStart;
int mTabGravity;
int mMode;
private OnTabSelectedListener mSelectedListener;
private final ArrayList<OnTabSelectedListener> mSelectedListeners = new ArrayList<>();
private OnTabSelectedListener mCurrentVpSelectedListener;
private ValueAnimator mScrollAnimator;
ViewPager mViewPager;
private PagerAdapter mPagerAdapter;
private DataSetObserver mPagerAdapterObserver;
private TabLayoutOnPageChangeListener mPageChangeListener;
private AdapterChangeListener mAdapterChangeListener;
private boolean mSetupViewPagerImplicitly;
// Pool we use as a simple RecyclerBin
private final Pools.Pool<TabView> mTabViewPool = new Pools.SimplePool<>(12);
public TabLayout(Context context) {
this(context, null);
}
public TabLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
ThemeUtils.checkAppCompatTheme(context);
// Disable the Scroll Bar
setHorizontalScrollBarEnabled(false);
// Add the TabStrip
mTabStrip = new SlidingTabStrip(context);
super.addView(mTabStrip, 0, new HorizontalScrollView.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TabLayout,
defStyleAttr, R.style.Widget_Design_TabLayout);
mTabStrip.setSelectedIndicatorHeight(
a.getDimensionPixelSize(R.styleable.TabLayout_tabIndicatorHeight, 0));
mTabPaddingStart = mTabPaddingTop = mTabPaddingEnd = mTabPaddingBottom = a
.getDimensionPixelSize(R.styleable.TabLayout_tabPadding, 0);
mTabPaddingStart = a.getDimensionPixelSize(R.styleable.TabLayout_tabPaddingStart,
mTabPaddingStart);
mTabPaddingTop = a.getDimensionPixelSize(R.styleable.TabLayout_tabPaddingTop,
mTabPaddingTop);
mTabPaddingEnd = a.getDimensionPixelSize(R.styleable.TabLayout_tabPaddingEnd,
mTabPaddingEnd);
mTabPaddingBottom = a.getDimensionPixelSize(R.styleable.TabLayout_tabPaddingBottom,
mTabPaddingBottom);
mTabTextAppearance = a.getResourceId(R.styleable.TabLayout_tabTextAppearance,
R.style.TextAppearance_Design_Tab);
// Text colors/sizes come from the text appearance first
final TypedArray ta = context.obtainStyledAttributes(mTabTextAppearance,
R.styleable.TextAppearance);
try {
mTabTextSize = ta.getDimensionPixelSize(
androidx.appcompat.R.styleable.TextAppearance_android_textSize, 0);
mTabTextColors = ta.getColorStateList(
androidx.appcompat.R.styleable.TextAppearance_android_textColor);
} finally {
ta.recycle();
}
if (a.hasValue(R.styleable.TabLayout_tabTextColor)) {
// If we have an explicit text color set, use it instead
mTabTextColors = a.getColorStateList(R.styleable.TabLayout_tabTextColor);
}
if (a.hasValue(R.styleable.TabLayout_tabSelectedTextColor)) {
// We have an explicit selected text color set, so we need to make merge it with the
// current colors. This is exposed so that developers can use theme attributes to set
// this (theme attrs in ColorStateLists are Lollipop+)
final int selected = a.getColor(R.styleable.TabLayout_tabSelectedTextColor, 0);
mTabTextColors = createColorStateList(mTabTextColors.getDefaultColor(), selected);
}
mRequestedTabMinWidth = a.getDimensionPixelSize(R.styleable.TabLayout_tabMinWidth,
INVALID_WIDTH);
mRequestedTabMaxWidth = a.getDimensionPixelSize(R.styleable.TabLayout_tabMaxWidth,
INVALID_WIDTH);
mTabBackgroundResId = a.getResourceId(R.styleable.TabLayout_tabBackground, 0);
mContentInsetStart = a.getDimensionPixelSize(R.styleable.TabLayout_tabContentStart, 0);
mMode = a.getInt(R.styleable.TabLayout_tabMode, MODE_FIXED);
mTabGravity = a.getInt(R.styleable.TabLayout_tabGravity, GRAVITY_FILL);
a.recycle();
TypedArray ma = context.obtainStyledAttributes(attrs, R.styleable.TabLayout);
int indicatorMarginStart = ma.getDimensionPixelSize(
R.styleable.TabLayout_indicatorMarginStart, 0);
int indicatorMarginEnd = ma.getDimensionPixelSize(
R.styleable.TabLayout_indicatorMarginEnd, 0);
int indicatorMarginBottom = ma.getDimensionPixelSize(
R.styleable.TabLayout_indicatorMarginBottom, 0);
int indicatorStartColor = ma.getColor(
R.styleable.TabLayout_indicatorStartColor, 0);
int indicatorEndColor = ma.getColor(
R.styleable.TabLayout_indicatorEndColor, 0);
mTabStrip.setSelectedIndicatorColor(indicatorStartColor, indicatorEndColor);
mTabStrip.setSelectedIndicatorMargin(indicatorMarginStart, indicatorMarginEnd);
mTabStrip.setSelectedIndicatorMarginBottom(indicatorMarginBottom);
ma.recycle();
// TODO add attr for these
final Resources res = getResources();
mTabTextMultiLineSize = res.getDimensionPixelSize(R.dimen.design_tab_text_size_2line);
mScrollableTabMinWidth = res.getDimensionPixelSize(R.dimen.design_tab_scrollable_min_width);
// Now apply the tab mode and gravity
applyModeAndGravity();
}
/**
* Sets the tab indicator's color for the currently selected tab.
*
* @param color color to use for the indicator
* @attr ref android.support.design.R.styleable#TabLayout_tabIndicatorColor
*/
public void setSelectedTabIndicatorColor(@ColorInt int color) {
mTabStrip.setSelectedIndicatorColor(color);
}
public void setSelectedTabIndicatorColor(@ColorInt int startColor, @ColorInt int endColor) {
mTabStrip.setSelectedIndicatorColor(startColor, endColor);
}
/**
* Sets the tab indicator's height for the currently selected tab.
*
* @param height height to use for the indicator in pixels
* @attr ref android.support.design.R.styleable#TabLayout_tabIndicatorHeight
*/
public void setSelectedTabIndicatorHeight(int height) {
mTabStrip.setSelectedIndicatorHeight(height);
}
/**
* Set the scroll position of the tabs. This is useful for when the tabs are being displayed as
* part of a scrolling container such as {@link androidx.viewpager}.
* <p>
* Calling this method does not update the selected tab, it is only used for drawing purposes.
*
* @param position current scroll position
* @param positionOffset Value from [0, 1) indicating the offset from {@code position}.
* @param updateSelectedText Whether to update the text's selected state.
*/
public void setScrollPosition(int position, float positionOffset, boolean updateSelectedText) {
setScrollPosition(position, positionOffset, updateSelectedText, true);
}
void setScrollPosition(int position, float positionOffset, boolean updateSelectedText,
boolean updateIndicatorPosition) {
final int roundedPosition = Math.round(position + positionOffset);
if (roundedPosition < 0 || roundedPosition >= mTabStrip.getChildCount()) {
return;
}
// Set the indicator position, if enabled
if (updateIndicatorPosition) {
mTabStrip.setIndicatorPositionFromTabPosition(position, positionOffset);
}
// Now update the scroll position, canceling any running animation
if (mScrollAnimator != null && mScrollAnimator.isRunning()) {
mScrollAnimator.cancel();
}
scrollTo(calculateScrollXForTab(position, positionOffset), 0);
// Update the 'selected state' view as we scroll, if enabled
if (updateSelectedText) {
setSelectedTabView(roundedPosition);
}
}
private float getScrollPosition() {
return mTabStrip.getIndicatorPosition();
}
/**
* Add a tab to this layout. The tab will be added at the end of the list.
* If this is the first tab to be added it will become the selected tab.
*
* @param tab Tab to add
*/
public void addTab(@NonNull Tab tab) {
addTab(tab, mTabs.isEmpty());
}
/**
* Add a tab to this layout. The tab will be inserted at <code>position</code>.
* If this is the first tab to be added it will become the selected tab.
*
* @param tab The tab to add
* @param position The new position of the tab
*/
public void addTab(@NonNull Tab tab, int position) {
addTab(tab, position, mTabs.isEmpty());
}
/**
* Add a tab to this layout. The tab will be added at the end of the list.
*
* @param tab Tab to add
* @param setSelected True if the added tab should become the selected tab.
*/
public void addTab(@NonNull Tab tab, boolean setSelected) {
addTab(tab, mTabs.size(), setSelected);
}
/**
* Add a tab to this layout. The tab will be inserted at <code>position</code>.
*
* @param tab The tab to add
* @param position The new position of the tab
* @param setSelected True if the added tab should become the selected tab.
*/
public void addTab(@NonNull Tab tab, int position, boolean setSelected) {
if (tab.mParent != this) {
throw new IllegalArgumentException("Tab belongs to a different TabLayout.");
}
configureTab(tab, position);
addTabView(tab);
if (setSelected) {
tab.select();
}
}
private void addTabFromItemView(@NonNull TabItem item) {
final Tab tab = newTab();
if (item.mText != null) {
tab.setText(item.mText);
}
if (item.mIcon != null) {
tab.setIcon(item.mIcon);
}
if (item.mCustomLayout != 0) {
tab.setCustomView(item.mCustomLayout);
}
if (!TextUtils.isEmpty(item.getContentDescription())) {
tab.setContentDescription(item.getContentDescription());
}
addTab(tab);
}
/**
* @deprecated Use {@link #addOnTabSelectedListener(OnTabSelectedListener)} and
* {@link #removeOnTabSelectedListener(OnTabSelectedListener)}.
*/
@Deprecated
public void setOnTabSelectedListener(@Nullable OnTabSelectedListener listener) {
// The logic in this method emulates what we had before support for multiple
// registered listeners.
if (mSelectedListener != null) {
removeOnTabSelectedListener(mSelectedListener);
}
// Update the deprecated field so that we can remove the passed listener the next
// time we're called
mSelectedListener = listener;
if (listener != null) {
addOnTabSelectedListener(listener);
}
}
/**
* Add a {@link TabLayout.OnTabSelectedListener} that will be invoked when tab selection
* changes.
*
* <p>Components that add a listener should take care to remove it when finished via
* {@link #removeOnTabSelectedListener(OnTabSelectedListener)}.</p>
*
* @param listener listener to add
*/
public void addOnTabSelectedListener(@NonNull OnTabSelectedListener listener) {
if (!mSelectedListeners.contains(listener)) {
mSelectedListeners.add(listener);
}
}
/**
* Remove the given {@link TabLayout.OnTabSelectedListener} that was previously added via
* {@link #addOnTabSelectedListener(OnTabSelectedListener)}.
*
* @param listener listener to remove
*/
public void removeOnTabSelectedListener(@NonNull OnTabSelectedListener listener) {
mSelectedListeners.remove(listener);
}
/**
* Remove all previously added {@link TabLayout.OnTabSelectedListener}s.
*/
public void clearOnTabSelectedListeners() {
mSelectedListeners.clear();
}
/**
* Create and return a new {@link Tab}. You need to manually add this using
* {@link #addTab(Tab)} or a related method.
*
* @return A new Tab
* @see #addTab(Tab)
*/
@NonNull
public Tab newTab() {
Tab tab = sTabPool.acquire();
if (tab == null) {
tab = new Tab();
}
tab.mParent = this;
tab.mView = createTabView(tab);
return tab;
}
/**
* Returns the number of tabs currently registered with the action bar.
*
* @return Tab count
*/
public int getTabCount() {
return mTabs.size();
}
/**
* Returns the tab at the specified index.
*/
@Nullable
public Tab getTabAt(int index) {
return (index < 0 || index >= getTabCount()) ? null : mTabs.get(index);
}
/**
* Returns the position of the current selected tab.
*
* @return selected tab position, or {@code -1} if there isn't a selected tab.
*/
public int getSelectedTabPosition() {
return mSelectedTab != null ? mSelectedTab.getPosition() : -1;
}
/**
* Remove a tab from the layout. If the removed tab was selected it will be deselected
* and another tab will be selected if present.
*
* @param tab The tab to remove
*/
public void removeTab(Tab tab) {
if (tab.mParent != this) {
throw new IllegalArgumentException("Tab does not belong to this TabLayout.");
}
removeTabAt(tab.getPosition());
}
/**
* Remove a tab from the layout. If the removed tab was selected it will be deselected
* and another tab will be selected if present.
*
* @param position Position of the tab to remove
*/
public void removeTabAt(int position) {
final int selectedTabPosition = mSelectedTab != null ? mSelectedTab.getPosition() : 0;
removeTabViewAt(position);
final Tab removedTab = mTabs.remove(position);
if (removedTab != null) {
removedTab.reset();
sTabPool.release(removedTab);
}
final int newTabCount = mTabs.size();
for (int i = position; i < newTabCount; i++) {
mTabs.get(i).setPosition(i);
}
if (selectedTabPosition == position) {
selectTab(mTabs.isEmpty() ? null : mTabs.get(Math.max(0, position - 1)));
}
}
/**
* Remove all tabs from the action bar and deselect the current tab.
*/
public void removeAllTabs() {
// Remove all the views
for (int i = mTabStrip.getChildCount() - 1; i >= 0; i--) {
removeTabViewAt(i);
}
for (final Iterator<Tab> i = mTabs.iterator(); i.hasNext(); ) {
final Tab tab = i.next();
i.remove();
tab.reset();
sTabPool.release(tab);
}
mSelectedTab = null;
}
/**
* Set the behavior mode for the Tabs in this layout. The valid input options are:
* <ul>
* <li>{@link #MODE_FIXED}: Fixed tabs display all tabs concurrently and are best used
* with content that benefits from quick pivots between tabs.</li>
* <li>{@link #MODE_SCROLLABLE}: Scrollable tabs display a subset of tabs at any given moment,
* and can contain longer tab labels and a larger number of tabs. They are best used for
* browsing contexts in touch interfaces when users don’t need to directly compare the tab
* labels. This mode is commonly used with a {@link androidx.viewpager}.</li>
* </ul>
*
* @param mode one of {@link #MODE_FIXED} or {@link #MODE_SCROLLABLE}.
* @attr ref android.support.design.R.styleable#TabLayout_tabMode
*/
public void setTabMode(@Mode int mode) {
if (mode != mMode) {
mMode = mode;
applyModeAndGravity();
}
}
/**
* Returns the current mode used by this {@link TabLayout}.
*
* @see #setTabMode(int)
*/
@Mode
public int getTabMode() {
return mMode;
}
/**
* Set the gravity to use when laying out the tabs.
*
* @param gravity one of {@link #GRAVITY_CENTER} or {@link #GRAVITY_FILL}.
* @attr ref android.support.design.R.styleable#TabLayout_tabGravity
*/
public void setTabGravity(@TabGravity int gravity) {
if (mTabGravity != gravity) {
mTabGravity = gravity;
applyModeAndGravity();
}
}
/**
* The current gravity used for laying out tabs.
*
* @return one of {@link #GRAVITY_CENTER} or {@link #GRAVITY_FILL}.
*/
@TabGravity
public int getTabGravity() {
return mTabGravity;
}
/**
* Sets the text colors for the different states (normal, selected) used for the tabs.
*
* @see #getTabTextColors()
*/
public void setTabTextColors(@Nullable ColorStateList textColor) {
if (mTabTextColors != textColor) {
mTabTextColors = textColor;
updateAllTabs();
}
}
/**
* Gets the text colors for the different states (normal, selected) used for the tabs.
*/
@Nullable
public ColorStateList getTabTextColors() {
return mTabTextColors;
}
/**
* Sets the text colors for the different states (normal, selected) used for the tabs.
*
* @attr ref android.support.design.R.styleable#TabLayout_tabTextColor
* @attr ref android.support.design.R.styleable#TabLayout_tabSelectedTextColor
*/
public void setTabTextColors(int normalColor, int selectedColor) {
setTabTextColors(createColorStateList(normalColor, selectedColor));
}
/**
* The one-stop shop for setting up this {@link TabLayout} with a {@link ViewPager}.
*
* <p>This is the same as calling {@link #setupWithViewPager(ViewPager, boolean)} with
* auto-refresh enabled.</p>
*
* @param viewPager the ViewPager to link to, or {@code null} to clear any previous link
*/
public void setupWithViewPager(@Nullable ViewPager viewPager) {
setupWithViewPager(viewPager, true);
}
/**
* The one-stop shop for setting up this {@link TabLayout} with a {@link ViewPager}.
*
* <p>This method will link the given ViewPager and this TabLayout together so that
* changes in one are automatically reflected in the other. This includes scroll state changes
* and clicks. The tabs displayed in this layout will be populated
* from the ViewPager adapter's page titles.</p>
*
* <p>If {@code autoRefresh} is {@code true}, any changes in the {@link PagerAdapter} will
* trigger this layout to re-populate itself from the adapter's titles.</p>
*
* <p>If the given ViewPager is non-null, it needs to already have a
* {@link PagerAdapter} set.</p>
*
* @param viewPager the ViewPager to link to, or {@code null} to clear any previous link
* @param autoRefresh whether this layout should refresh its contents if the given ViewPager's
* content changes
*/
public void setupWithViewPager(@Nullable final ViewPager viewPager, boolean autoRefresh) {
setupWithViewPager(viewPager, autoRefresh, false);
}
private void setupWithViewPager(@Nullable final ViewPager viewPager, boolean autoRefresh,
boolean implicitSetup) {
if (mViewPager != null) {
// If we've already been setup with a ViewPager, remove us from it
if (mPageChangeListener != null) {
mViewPager.removeOnPageChangeListener(mPageChangeListener);
}
if (mAdapterChangeListener != null) {
mViewPager.removeOnAdapterChangeListener(mAdapterChangeListener);
}
}
if (mCurrentVpSelectedListener != null) {
// If we already have a tab selected listener for the ViewPager, remove it
removeOnTabSelectedListener(mCurrentVpSelectedListener);
mCurrentVpSelectedListener = null;
}
if (viewPager != null) {
mViewPager = viewPager;
// Add our custom OnPageChangeListener to the ViewPager
if (mPageChangeListener == null) {
mPageChangeListener = new TabLayoutOnPageChangeListener(this);
}
mPageChangeListener.reset();
viewPager.addOnPageChangeListener(mPageChangeListener);
// Now we'll add a tab selected listener to set ViewPager's current item
mCurrentVpSelectedListener = new ViewPagerOnTabSelectedListener(viewPager);
addOnTabSelectedListener(mCurrentVpSelectedListener);
final PagerAdapter adapter = viewPager.getAdapter();
if (adapter != null) {
// Now we'll populate ourselves from the pager adapter, adding an observer if
// autoRefresh is enabled
setPagerAdapter(adapter, autoRefresh);
}
// Add a listener so that we're notified of any adapter changes
if (mAdapterChangeListener == null) {
mAdapterChangeListener = new AdapterChangeListener();
}
mAdapterChangeListener.setAutoRefresh(autoRefresh);
viewPager.addOnAdapterChangeListener(mAdapterChangeListener);
// Now update the scroll position to match the ViewPager's current item
setScrollPosition(viewPager.getCurrentItem(), 0f, true);
} else {
// We've been given a null ViewPager so we need to clear out the internal state,
// listeners and observers
mViewPager = null;
setPagerAdapter(null, false);
}
mSetupViewPagerImplicitly = implicitSetup;
}
/**
* @deprecated Use {@link #setupWithViewPager(ViewPager)} to link a TabLayout with a ViewPager
* together. When that method is used, the TabLayout will be automatically updated
* when the {@link PagerAdapter} is changed.
*/
@Deprecated
public void setTabsFromPagerAdapter(@Nullable final PagerAdapter adapter) {
setPagerAdapter(adapter, false);
}
@Override
public boolean shouldDelayChildPressedState() {
// Only delay the pressed state if the tabs can scroll
return getTabScrollRange() > 0;
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (mViewPager == null) {
// If we don't have a ViewPager already, check if our parent is a ViewPager to
// setup with it automatically
final ViewParent vp = getParent();
if (vp instanceof ViewPager) {
// If we have a ViewPager parent and we've been added as part of its decor, let's
// assume that we should automatically setup to display any titles
setupWithViewPager((ViewPager) vp, true, true);
}
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mSetupViewPagerImplicitly) {
// If we've been setup with a ViewPager implicitly, let's clear out any listeners, etc
setupWithViewPager(null);
mSetupViewPagerImplicitly = false;
}
}
private int getTabScrollRange() {
return Math.max(0, mTabStrip.getWidth() - getWidth() - getPaddingLeft()
- getPaddingRight());
}
void setPagerAdapter(@Nullable final PagerAdapter adapter, final boolean addObserver) {
if (mPagerAdapter != null && mPagerAdapterObserver != null) {
// If we already have a PagerAdapter, unregister our observer
mPagerAdapter.unregisterDataSetObserver(mPagerAdapterObserver);
}
mPagerAdapter = adapter;
if (addObserver && adapter != null) {
// Register our observer on the new adapter
if (mPagerAdapterObserver == null) {
mPagerAdapterObserver = new PagerAdapterObserver();
}
adapter.registerDataSetObserver(mPagerAdapterObserver);
}
// Finally make sure we reflect the new adapter
populateFromPagerAdapter();
}
void populateFromPagerAdapter() {
removeAllTabs();
if (mPagerAdapter != null) {
final int adapterCount = mPagerAdapter.getCount();
for (int i = 0; i < adapterCount; i++) {
addTab(newTab().setText(mPagerAdapter.getPageTitle(i)), false);
}
// Make sure we reflect the currently set ViewPager item
if (mViewPager != null && adapterCount > 0) {
final int curItem = mViewPager.getCurrentItem();
if (curItem != getSelectedTabPosition() && curItem < getTabCount()) {
selectTab(getTabAt(curItem));
}
}
}
}
private void updateAllTabs() {
for (int i = 0, z = mTabs.size(); i < z; i++) {
mTabs.get(i).updateView();
}
}
private TabView createTabView(@NonNull final Tab tab) {
TabView tabView = mTabViewPool != null ? mTabViewPool.acquire() : null;
if (tabView == null) {
tabView = new TabView(getContext());
}
tabView.setTab(tab);
tabView.setFocusable(true);
tabView.setMinimumWidth(getTabMinWidth());
return tabView;
}
private void configureTab(Tab tab, int position) {
tab.setPosition(position);
mTabs.add(position, tab);
final int count = mTabs.size();
for (int i = position + 1; i < count; i++) {
mTabs.get(i).setPosition(i);
}
}
private void addTabView(Tab tab) {
final TabView tabView = tab.mView;
mTabStrip.addView(tabView, tab.getPosition(), createLayoutParamsForTabs());
}
@Override
public void addView(View child) {
addViewInternal(child);
}
@Override
public void addView(View child, int index) {
addViewInternal(child);
}
@Override
public void addView(View child, ViewGroup.LayoutParams params) {
addViewInternal(child);
}
@Override
public void addView(View child, int index, ViewGroup.LayoutParams params) {
addViewInternal(child);
}
private void addViewInternal(final View child) {
if (child instanceof TabItem) {
addTabFromItemView((TabItem) child);
} else {
throw new IllegalArgumentException("Only TabItem instances can be added to TabLayout");
}
}
private LinearLayout.LayoutParams createLayoutParamsForTabs() {
final LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
updateTabViewLayoutParams(lp);
return lp;
}
private void updateTabViewLayoutParams(LinearLayout.LayoutParams lp) {
if (mMode == MODE_FIXED && mTabGravity == GRAVITY_FILL) {
lp.width = 0;
lp.weight = 1;
} else {
lp.width = LinearLayout.LayoutParams.WRAP_CONTENT;
lp.weight = 0;
}
}
int dpToPx(int dps) {
return Math.round(getResources().getDisplayMetrics().density * dps);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// If we have a MeasureSpec which allows us to decide our height, try and use the default
// height
final int idealHeight = dpToPx(getDefaultHeight()) + getPaddingTop() + getPaddingBottom();
switch (MeasureSpec.getMode(heightMeasureSpec)) {
case MeasureSpec.AT_MOST:
heightMeasureSpec = MeasureSpec.makeMeasureSpec(
Math.min(idealHeight, MeasureSpec.getSize(heightMeasureSpec)),
MeasureSpec.EXACTLY);
break;
case MeasureSpec.UNSPECIFIED:
heightMeasureSpec = MeasureSpec.makeMeasureSpec(idealHeight, MeasureSpec.EXACTLY);
break;
}
final int specWidth = MeasureSpec.getSize(widthMeasureSpec);
if (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.UNSPECIFIED) {
// If we don't have an unspecified width spec, use the given size to calculate
// the max tab width
mTabMaxWidth = mRequestedTabMaxWidth > 0
? mRequestedTabMaxWidth
: specWidth - dpToPx(TAB_MIN_WIDTH_MARGIN);
}
// Now super measure itself using the (possibly) modified height spec
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (getChildCount() == 1) {
// If we're in fixed mode then we need to make the tab strip is the same width as us
// so we don't scroll
final View child = getChildAt(0);
boolean remeasure = false;
switch (mMode) {
case MODE_SCROLLABLE:
// We only need to resize the child if it's smaller than us. This is similar
// to fillViewport
remeasure = child.getMeasuredWidth() < getMeasuredWidth();
break;
case MODE_FIXED:
// Resize the child so that it doesn't scroll
remeasure = child.getMeasuredWidth() != getMeasuredWidth();
break;
}
if (remeasure) {
// Re-measure the child with a widthSpec set to be exactly our measure width
int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, getPaddingTop()
+ getPaddingBottom(), child.getLayoutParams().height);
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
getMeasuredWidth(), MeasureSpec.EXACTLY);
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
}
}
private void removeTabViewAt(int position) {
final TabView view = (TabView) mTabStrip.getChildAt(position);
mTabStrip.removeViewAt(position);
if (view != null) {
view.reset();
mTabViewPool.release(view);
}
requestLayout();
}
private void animateToTab(int newPosition) {
if (newPosition == Tab.INVALID_POSITION) {
return;
}
if (getWindowToken() == null || !ViewCompat.isLaidOut(this)
|| mTabStrip.childrenNeedLayout()) {
// If we don't have a window token, or we haven't been laid out yet just draw the new
// position now
setScrollPosition(newPosition, 0f, true);
return;
}
final int startScrollX = getScrollX();
final int targetScrollX = calculateScrollXForTab(newPosition, 0);
if (startScrollX != targetScrollX) {
ensureScrollAnimator();
mScrollAnimator.setIntValues(startScrollX, targetScrollX);
mScrollAnimator.start();
}
// Now animate the indicator
mTabStrip.animateIndicatorToPosition(newPosition, ANIMATION_DURATION);
}
private void ensureScrollAnimator() {
if (mScrollAnimator == null) {
mScrollAnimator = new ValueAnimator();
mScrollAnimator.setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR);
mScrollAnimator.setDuration(ANIMATION_DURATION);
mScrollAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animator) {
scrollTo((int) animator.getAnimatedValue(), 0);
}
});
}
}
void setScrollAnimatorListener(Animator.AnimatorListener listener) {
ensureScrollAnimator();
mScrollAnimator.addListener(listener);
}
private void setSelectedTabView(int position) {
final int tabCount = mTabStrip.getChildCount();
if (position < tabCount) {
for (int i = 0; i < tabCount; i++) {
final View child = mTabStrip.getChildAt(i);
child.setSelected(i == position);
}
}
}
void selectTab(Tab tab) {
selectTab(tab, true);
}
void selectTab(final Tab tab, boolean updateIndicator) {
final Tab currentTab = mSelectedTab;
if (currentTab == tab) {
if (currentTab != null) {
dispatchTabReselected(tab);
animateToTab(tab.getPosition());
}
} else {
final int newPosition = tab != null ? tab.getPosition() : Tab.INVALID_POSITION;
if (updateIndicator) {
if ((currentTab == null || currentTab.getPosition() == Tab.INVALID_POSITION)
&& newPosition != Tab.INVALID_POSITION) {
// If we don't currently have a tab, just draw the indicator
setScrollPosition(newPosition, 0f, true);
} else {
animateToTab(newPosition);
}
if (newPosition != Tab.INVALID_POSITION) {
setSelectedTabView(newPosition);
}
}
if (currentTab != null) {
dispatchTabUnselected(currentTab);
}
mSelectedTab = tab;
if (tab != null) {
dispatchTabSelected(tab);
}
}
}
private void dispatchTabSelected(@NonNull final Tab tab) {
for (int i = mSelectedListeners.size() - 1; i >= 0; i--) {
mSelectedListeners.get(i).onTabSelected(tab);
}
}
private void dispatchTabUnselected(@NonNull final Tab tab) {
for (int i = mSelectedListeners.size() - 1; i >= 0; i--) {
mSelectedListeners.get(i).onTabUnselected(tab);
}
}
private void dispatchTabReselected(@NonNull final Tab tab) {
for (int i = mSelectedListeners.size() - 1; i >= 0; i--) {
mSelectedListeners.get(i).onTabReselected(tab);
}
}
private int calculateScrollXForTab(int position, float positionOffset) {
if (mMode == MODE_SCROLLABLE) {
final View selectedChild = mTabStrip.getChildAt(position);
final View nextChild = position + 1 < mTabStrip.getChildCount()
? mTabStrip.getChildAt(position + 1)
: null;
final int selectedWidth = selectedChild != null ? selectedChild.getWidth() : 0;
final int nextWidth = nextChild != null ? nextChild.getWidth() : 0;
// base scroll amount: places center of tab in center of parent
int scrollBase = selectedChild.getLeft() + (selectedWidth / 2) - (getWidth() / 2);
// offset amount: fraction of the distance between centers of tabs
int scrollOffset = (int) ((selectedWidth + nextWidth) * 0.5f * positionOffset);
return (ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_LTR)
? scrollBase + scrollOffset
: scrollBase - scrollOffset;
}
return 0;
}
private void applyModeAndGravity() {
int paddingStart = 0;
if (mMode == MODE_SCROLLABLE) {
// If we're scrollable, or fixed at start, inset using padding
paddingStart = Math.max(0, mContentInsetStart - mTabPaddingStart);
}
ViewCompat.setPaddingRelative(mTabStrip, paddingStart, 0, 0, 0);
switch (mMode) {
case MODE_FIXED:
mTabStrip.setGravity(Gravity.CENTER_HORIZONTAL);
break;
case MODE_SCROLLABLE:
mTabStrip.setGravity(GravityCompat.START);
break;
}
updateTabViews(true);
}
void updateTabViews(final boolean requestLayout) {
for (int i = 0; i < mTabStrip.getChildCount(); i++) {
View child = mTabStrip.getChildAt(i);
child.setMinimumWidth(getTabMinWidth());
updateTabViewLayoutParams((LinearLayout.LayoutParams) child.getLayoutParams());
if (requestLayout) {
child.requestLayout();
}
}
}
/**
* A tab in this layout. Instances can be created via {@link #newTab()}.
*/
public static final class Tab {
/**
* An invalid position for a tab.
*
* @see #getPosition()
*/
public static final int INVALID_POSITION = -1;
private Object mTag;
private Drawable mIcon;
private CharSequence mText;
private CharSequence mContentDesc;
private int mPosition = INVALID_POSITION;
private View mCustomView;
TabLayout mParent;
TabView mView;
Tab() {
// Private constructor
}
/**
* @return This Tab's tag object.
*/
@Nullable
public Object getTag() {
return mTag;
}
/**
* Give this Tab an arbitrary object to hold for later use.
*
* @param tag Object to store
* @return The current instance for call chaining
*/
@NonNull
public Tab setTag(@Nullable Object tag) {
mTag = tag;
return this;
}
/**
* Returns the custom view used for this tab.
*
* @see #setCustomView(View)
* @see #setCustomView(int)
*/
@Nullable
public View getCustomView() {
return mCustomView;
}
/**
* Set a custom view to be used for this tab.
* <p>
* If the provided view contains a {@link TextView} with an ID of
* {@link android.R.id#text1} then that will be updated with the value given
* to {@link #setText(CharSequence)}. Similarly, if this layout contains an
* {@link ImageView} with ID {@link android.R.id#icon} then it will be updated with
* the value given to {@link #setIcon(Drawable)}.
* </p>
*
* @param view Custom view to be used as a tab.
* @return The current instance for call chaining
*/
@NonNull
public Tab setCustomView(@Nullable View view) {
mCustomView = view;
updateView();
return this;
}
/**
* Set a custom view to be used for this tab.
* <p>
* If the inflated layout contains a {@link TextView} with an ID of
* {@link android.R.id#text1} then that will be updated with the value given
* to {@link #setText(CharSequence)}. Similarly, if this layout contains an
* {@link ImageView} with ID {@link android.R.id#icon} then it will be updated with
* the value given to {@link #setIcon(Drawable)}.
* </p>
*
* @param resId A layout resource to inflate and use as a custom tab view
* @return The current instance for call chaining
*/
@NonNull
public Tab setCustomView(@LayoutRes int resId) {
final LayoutInflater inflater = LayoutInflater.from(mView.getContext());
return setCustomView(inflater.inflate(resId, mView, false));
}
/**
* Return the icon associated with this tab.
*
* @return The tab's icon
*/
@Nullable
public Drawable getIcon() {
return mIcon;
}
/**
* Return the current position of this tab in the action bar.
*
* @return Current position, or {@link #INVALID_POSITION} if this tab is not currently in
* the action bar.
*/
public int getPosition() {
return mPosition;
}
void setPosition(int position) {
mPosition = position;
}
/**
* Return the text of this tab.
*
* @return The tab's text
*/
@Nullable
public CharSequence getText() {
return mText;
}
/**
* Set the icon displayed on this tab.
*
* @param icon The drawable to use as an icon
* @return The current instance for call chaining
*/
@NonNull
public Tab setIcon(@Nullable Drawable icon) {
mIcon = icon;
updateView();
return this;
}
/**
* Set the icon displayed on this tab.
*
* @param resId A resource ID referring to the icon that should be displayed
* @return The current instance for call chaining
*/
@NonNull
public Tab setIcon(@DrawableRes int resId) {
if (mParent == null) {
throw new IllegalArgumentException("Tab not attached to a TabLayout");
}
return setIcon(AppCompatResources.getDrawable(mParent.getContext(), resId));
}
/**
* Set the text displayed on this tab. Text may be truncated if there is not room to display
* the entire string.
*
* @param text The text to display
* @return The current instance for call chaining
*/
@NonNull
public Tab setText(@Nullable CharSequence text) {
mText = text;
updateView();
return this;
}
/**
* Set the text displayed on this tab. Text may be truncated if there is not room to display
* the entire string.
*
* @param resId A resource ID referring to the text that should be displayed
* @return The current instance for call chaining
*/
@NonNull
public Tab setText(@StringRes int resId) {
if (mParent == null) {
throw new IllegalArgumentException("Tab not attached to a TabLayout");
}
return setText(mParent.getResources().getText(resId));
}
/**
* Select this tab. Only valid if the tab has been added to the action bar.
*/
public void select() {
if (mParent == null) {
throw new IllegalArgumentException("Tab not attached to a TabLayout");
}
mParent.selectTab(this);
}
/**
* Returns true if this tab is currently selected.
*/
public boolean isSelected() {
if (mParent == null) {
throw new IllegalArgumentException("Tab not attached to a TabLayout");
}
return mParent.getSelectedTabPosition() == mPosition;
}
/**
* Set a description of this tab's content for use in accessibility support. If no content
* description is provided the title will be used.
*
* @param resId A resource ID referring to the description text
* @return The current instance for call chaining
* @see #setContentDescription(CharSequence)
* @see #getContentDescription()
*/
@NonNull
public Tab setContentDescription(@StringRes int resId) {
if (mParent == null) {
throw new IllegalArgumentException("Tab not attached to a TabLayout");
}
return setContentDescription(mParent.getResources().getText(resId));
}
/**
* Set a description of this tab's content for use in accessibility support. If no content
* description is provided the title will be used.
*
* @param contentDesc Description of this tab's content
* @return The current instance for call chaining
* @see #setContentDescription(int)
* @see #getContentDescription()
*/
@NonNull
public Tab setContentDescription(@Nullable CharSequence contentDesc) {
mContentDesc = contentDesc;
updateView();
return this;
}
/**
* Gets a brief description of this tab's content for use in accessibility support.
*
* @return Description of this tab's content
* @see #setContentDescription(CharSequence)
* @see #setContentDescription(int)
*/
@Nullable
public CharSequence getContentDescription() {
return mContentDesc;
}
void updateView() {
if (mView != null) {
mView.update();
}
}
void reset() {
mParent = null;
mView = null;
mTag = null;
mIcon = null;
mText = null;
mContentDesc = null;
mPosition = INVALID_POSITION;
mCustomView = null;
}
}
class TabView extends LinearLayout {
private Tab mTab;
private TextView mTextView;
private ImageView mIconView;
private View mCustomView;
private TextView mCustomTextView;
private ImageView mCustomIconView;
private int mDefaultMaxLines = 2;
public TabView(Context context) {
super(context);
if (mTabBackgroundResId != 0) {
ViewCompat.setBackground(
this, AppCompatResources.getDrawable(context, mTabBackgroundResId));
}
ViewCompat.setPaddingRelative(this, mTabPaddingStart, mTabPaddingTop,
mTabPaddingEnd, mTabPaddingBottom);
setGravity(Gravity.CENTER);
setOrientation(VERTICAL);
setClickable(true);
ViewCompat.setPointerIcon(this,
PointerIconCompat.getSystemIcon(getContext(), PointerIconCompat.TYPE_HAND));
}
@Override
public boolean performClick() {
final boolean handled = super.performClick();
if (mTab != null) {
if (!handled) {
playSoundEffect(SoundEffectConstants.CLICK);
}
mTab.select();
return true;
} else {
return handled;
}
}
@Override
public void setSelected(final boolean selected) {
final boolean changed = isSelected() != selected;
super.setSelected(selected);
if (changed && selected && Build.VERSION.SDK_INT < 16) {
// Pre-JB we need to manually send the TYPE_VIEW_SELECTED event
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
}
// Always dispatch this to the child views, regardless of whether the value has
// changed
if (mTextView != null) {
mTextView.setSelected(selected);
}
if (mIconView != null) {
mIconView.setSelected(selected);
}
if (mCustomView != null) {
mCustomView.setSelected(selected);
}
}
@Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
// This view masquerades as an action bar tab.
event.setClassName(ActionBar.Tab.class.getName());
}
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
// This view masquerades as an action bar tab.
info.setClassName(ActionBar.Tab.class.getName());
}
@Override
public void onMeasure(final int origWidthMeasureSpec, final int origHeightMeasureSpec) {
final int specWidthSize = MeasureSpec.getSize(origWidthMeasureSpec);
final int specWidthMode = MeasureSpec.getMode(origWidthMeasureSpec);
final int maxWidth = getTabMaxWidth();
final int widthMeasureSpec;
final int heightMeasureSpec = origHeightMeasureSpec;
if (maxWidth > 0 && (specWidthMode == MeasureSpec.UNSPECIFIED
|| specWidthSize > maxWidth)) {
// If we have a max width and a given spec which is either unspecified or
// larger than the max width, update the width spec using the same mode
widthMeasureSpec = MeasureSpec.makeMeasureSpec(mTabMaxWidth, MeasureSpec.AT_MOST);
} else {
// Else, use the original width spec
widthMeasureSpec = origWidthMeasureSpec;
}
// Now lets measure
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// We need to switch the text size based on whether the text is spanning 2 lines or not
if (mTextView != null) {
final Resources res = getResources();
float textSize = mTabTextSize;
int maxLines = mDefaultMaxLines;
if (mIconView != null && mIconView.getVisibility() == VISIBLE) {
// If the icon view is being displayed, we limit the text to 1 line
maxLines = 1;
} else if (mTextView != null && mTextView.getLineCount() > 1) {
// Otherwise when we have text which wraps we reduce the text size
textSize = mTabTextMultiLineSize;
}
final float curTextSize = mTextView.getTextSize();
final int curLineCount = mTextView.getLineCount();
final int curMaxLines = TextViewCompat.getMaxLines(mTextView);
if (textSize != curTextSize || (curMaxLines >= 0 && maxLines != curMaxLines)) {
// We've got a new text size and/or max lines...
boolean updateTextView = true;
if (mMode == MODE_FIXED && textSize > curTextSize && curLineCount == 1) {
// If we're in fixed mode, going up in text size and currently have 1 line
// then it's very easy to get into an infinite recursion.
// To combat that we check to see if the change in text size
// will cause a line count change. If so, abort the size change and stick
// to the smaller size.
final Layout layout = mTextView.getLayout();
if (layout == null || approximateLineWidth(layout, 0, textSize)
> getMeasuredWidth() - getPaddingLeft() - getPaddingRight()) {
updateTextView = false;
}
}
if (updateTextView) {
mTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
mTextView.setMaxLines(maxLines);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
}
void setTab(@Nullable final Tab tab) {
if (tab != mTab) {
mTab = tab;
update();
}
}
void reset() {
setTab(null);
setSelected(false);
}
final void update() {
final Tab tab = mTab;
final View custom = tab != null ? tab.getCustomView() : null;
if (custom != null) {
final ViewParent customParent = custom.getParent();
if (customParent != this) {
if (customParent != null) {
((ViewGroup) customParent).removeView(custom);
}
addView(custom);
}
mCustomView = custom;
if (mTextView != null) {
mTextView.setVisibility(GONE);
}
if (mIconView != null) {
mIconView.setVisibility(GONE);
mIconView.setImageDrawable(null);
}
mCustomTextView = (TextView) custom.findViewById(android.R.id.text1);
if (mCustomTextView != null) {
mDefaultMaxLines = TextViewCompat.getMaxLines(mCustomTextView);
}
mCustomIconView = (ImageView) custom.findViewById(android.R.id.icon);
} else {
// We do not have a custom view. Remove one if it already exists
if (mCustomView != null) {
removeView(mCustomView);
mCustomView = null;
}
mCustomTextView = null;
mCustomIconView = null;
}
if (mCustomView == null) {
// If there isn't a custom view, we'll us our own in-built layouts
if (mIconView == null) {
ImageView iconView = (ImageView) LayoutInflater.from(getContext())
.inflate(R.layout.design_layout_tab_icon, this, false);
addView(iconView, 0);
mIconView = iconView;
}
if (mTextView == null) {
TextView textView = (TextView) LayoutInflater.from(getContext())
.inflate(R.layout.design_layout_tab_text, this, false);
addView(textView);
mTextView = textView;
mDefaultMaxLines = TextViewCompat.getMaxLines(mTextView);
}
TextViewCompat.setTextAppearance(mTextView, mTabTextAppearance);
if (mTabTextColors != null) {
mTextView.setTextColor(mTabTextColors);
}
updateTextAndIcon(mTextView, mIconView);
} else {
// Else, we'll see if there is a TextView or ImageView present and update them
if (mCustomTextView != null || mCustomIconView != null) {
updateTextAndIcon(mCustomTextView, mCustomIconView);
}
}
// Finally update our selected state
setSelected(tab != null && tab.isSelected());
}
private void updateTextAndIcon(@Nullable final TextView textView,
@Nullable final ImageView iconView) {
final Drawable icon = mTab != null ? mTab.getIcon() : null;
final CharSequence text = mTab != null ? mTab.getText() : null;
final CharSequence contentDesc = mTab != null ? mTab.getContentDescription() : null;
if (iconView != null) {
if (icon != null) {
iconView.setImageDrawable(icon);
iconView.setVisibility(VISIBLE);
setVisibility(VISIBLE);
} else {
iconView.setVisibility(GONE);
iconView.setImageDrawable(null);
}
iconView.setContentDescription(contentDesc);
}
final boolean hasText = !TextUtils.isEmpty(text);
if (textView != null) {
if (hasText) {
textView.setText(text);
textView.setVisibility(VISIBLE);
setVisibility(VISIBLE);
} else {
textView.setVisibility(GONE);
textView.setText(null);
}
textView.setContentDescription(contentDesc);
}
if (iconView != null) {
MarginLayoutParams lp = ((MarginLayoutParams) iconView.getLayoutParams());
int bottomMargin = 0;
if (hasText && iconView.getVisibility() == VISIBLE) {
// If we're showing both text and icon, add some margin bottom to the icon
bottomMargin = dpToPx(DEFAULT_GAP_TEXT_ICON);
}
if (bottomMargin != lp.bottomMargin) {
lp.bottomMargin = bottomMargin;
iconView.requestLayout();
}
}
TooltipCompat.setTooltipText(this, hasText ? null : contentDesc);
}
public Tab getTab() {
return mTab;
}
/**
* Approximates a given lines width with the new provided text size.
*/
private float approximateLineWidth(Layout layout, int line, float textSize) {
return layout.getLineWidth(line) * (textSize / layout.getPaint().getTextSize());
}
}
private class SlidingTabStrip extends LinearLayout {
private int mSelectedIndicatorHeight;
private final Paint mSelectedIndicatorPaint;
int mSelectedPosition = -1;
float mSelectionOffset;
private int mLayoutDirection = -1;
private int mIndicatorLeft = -1;
private int mIndicatorRight = -1;
private RectF mIndicatorRect = new RectF();
private int mIndicatorMarginLeft = 0;
private int mIndicatorMarginRight = 0;
private int mIndicatorMarginBottom = 0;
private ValueAnimator mIndicatorAnimator;
private int mStartColor;
private int mEndColor;
private boolean mIsColorDirty = true;
SlidingTabStrip(Context context) {
super(context);
setWillNotDraw(false);
mSelectedIndicatorPaint = new Paint();
mSelectedIndicatorPaint.setAntiAlias(true);
}
void setSelectedIndicatorMarginBottom(@Px int margin) {
mIndicatorMarginBottom = margin;
}
void setSelectedIndicatorMargin(@Px int marginLeft, @Px int marginRight) {
mIndicatorMarginLeft = marginLeft;
mIndicatorMarginRight = marginRight;
}
void setSelectedIndicatorColor(int color) {
setSelectedIndicatorColor(color, color);
}
void setSelectedIndicatorColor(int startColor, int endColor) {
if (startColor != mStartColor || endColor != mEndColor) {
mStartColor = startColor;
mEndColor = endColor;
mIsColorDirty = true;
ViewCompat.postInvalidateOnAnimation(this);
}
}
void setSelectedIndicatorHeight(int height) {
if (mSelectedIndicatorHeight != height) {
mSelectedIndicatorHeight = height;
ViewCompat.postInvalidateOnAnimation(this);
}
}
boolean childrenNeedLayout() {
for (int i = 0, z = getChildCount(); i < z; i++) {
final View child = getChildAt(i);
if (child.getWidth() <= 0) {
return true;
}
}
return false;
}
void setIndicatorPositionFromTabPosition(int position, float positionOffset) {
if (mIndicatorAnimator != null && mIndicatorAnimator.isRunning()) {
mIndicatorAnimator.cancel();
}
mSelectedPosition = position;
mSelectionOffset = positionOffset;
updateIndicatorPosition();
}
float getIndicatorPosition() {
return mSelectedPosition + mSelectionOffset;
}
@Override
public void onRtlPropertiesChanged(int layoutDirection) {
super.onRtlPropertiesChanged(layoutDirection);
// Workaround for a bug before Android M where LinearLayout did not relayout itself when
// layout direction changed.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
//noinspection WrongConstant
if (mLayoutDirection != layoutDirection) {
requestLayout();
mLayoutDirection = layoutDirection;
}
}
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY) {
// HorizontalScrollView will first measure use with UNSPECIFIED, and then with
// EXACTLY. Ignore the first call since anything we do will be overwritten anyway
return;
}
if (mMode == MODE_FIXED && mTabGravity == GRAVITY_CENTER) {
final int count = getChildCount();
// First we'll find the widest tab
int largestTabWidth = 0;
for (int i = 0, z = count; i < z; i++) {
View child = getChildAt(i);
if (child.getVisibility() == VISIBLE) {
largestTabWidth = Math.max(largestTabWidth, child.getMeasuredWidth());
}
}
if (largestTabWidth <= 0) {
// If we don't have a largest child yet, skip until the next measure pass
return;
}
final int gutter = dpToPx(FIXED_WRAP_GUTTER_MIN);
boolean remeasure = false;
if (largestTabWidth * count <= getMeasuredWidth() - gutter * 2) {
// If the tabs fit within our width minus gutters, we will set all tabs to have
// the same width
for (int i = 0; i < count; i++) {
final LinearLayout.LayoutParams lp =
(LayoutParams) getChildAt(i).getLayoutParams();
if (lp.width != largestTabWidth || lp.weight != 0) {
lp.width = largestTabWidth;
lp.weight = 0;
remeasure = true;
}
}
} else {
// If the tabs will wrap to be larger than the width minus gutters, we need
// to switch to GRAVITY_FILL
mTabGravity = GRAVITY_FILL;
updateTabViews(false);
remeasure = true;
}
if (remeasure) {
// Now re-measure after our changes
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (mIndicatorAnimator != null && mIndicatorAnimator.isRunning()) {
// If we're currently running an animation, lets cancel it and start a
// new animation with the remaining duration
mIndicatorAnimator.cancel();
final long duration = mIndicatorAnimator.getDuration();
animateIndicatorToPosition(mSelectedPosition,
Math.round((1f - mIndicatorAnimator.getAnimatedFraction()) * duration));
} else {
// If we've been layed out, update the indicator position
updateIndicatorPosition();
}
}
@SuppressLint("RestrictedApi")
private void updateIndicatorPosition() {
final View selectedTitle = getChildAt(mSelectedPosition);
int left, right;
if (selectedTitle != null && selectedTitle.getWidth() > 0) {
left = selectedTitle.getLeft();
right = selectedTitle.getRight();
if (mSelectionOffset > 0f && mSelectedPosition < getChildCount() - 1) {
// Draw the selection partway between the tabs
View nextTitle = getChildAt(mSelectedPosition + 1);
if (mSelectionOffset <= 0.5f) {
left = selectedTitle.getLeft();
right = AnimationUtils.lerp(right, nextTitle.getRight(), mSelectionOffset * 2);
} else {
left = AnimationUtils.lerp(left, nextTitle.getLeft(), (mSelectionOffset - 0.5f) * 2);
right = nextTitle.getRight();
}
}
} else {
left = right = -1;
}
setIndicatorPosition(left, right);
}
void setIndicatorPosition(int left, int right) {
if (left != mIndicatorLeft || right != mIndicatorRight) {
// If the indicator's left/right has changed, invalidate
mIndicatorLeft = left + mIndicatorMarginLeft;
mIndicatorRight = right - mIndicatorMarginRight;
ViewCompat.postInvalidateOnAnimation(this);
}
}
void animateIndicatorToPosition(final int position, int duration) {
if (mIndicatorAnimator != null && mIndicatorAnimator.isRunning()) {
mIndicatorAnimator.cancel();
}
final boolean isRtl = ViewCompat.getLayoutDirection(this)
== ViewCompat.LAYOUT_DIRECTION_RTL;
final View targetView = getChildAt(position);
if (targetView == null) {
// If we don't have a view, just update the position now and return
updateIndicatorPosition();
return;
}
final int targetLeft = targetView.getLeft();
final int targetRight = targetView.getRight();
final int startLeft;
final int startRight;
startLeft = mIndicatorLeft;
startRight = mIndicatorRight;
if (startLeft != targetLeft || startRight != targetRight) {
ValueAnimator animator = mIndicatorAnimator = new ValueAnimator();
animator.setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR);
animator.setDuration(duration);
animator.setFloatValues(0, 1);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@SuppressLint("RestrictedApi")
@Override
public void onAnimationUpdate(ValueAnimator animator) {
final float fraction = animator.getAnimatedFraction();
int left, right;
if (mSelectedPosition < position) {
if (fraction <= 0.5f) {
left = startLeft;
right = AnimationUtils.lerp(startRight, targetRight, fraction * 2);
} else {
left = AnimationUtils.lerp(startLeft, targetLeft, (fraction - 0.5f) * 2);
right = targetRight;
}
} else {
if (fraction <= 0.5f) {
left = AnimationUtils.lerp(startLeft, targetLeft, fraction * 2);
right = startRight;
} else {
left = targetLeft;
right = AnimationUtils.lerp(startRight, targetRight, (fraction - 0.5f) * 2);
}
}
setIndicatorPosition(left, right);
}
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animator) {
mSelectedPosition = position;
mSelectionOffset = 0f;
}
});
animator.start();
}
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
int left = mIndicatorLeft;
int right = mIndicatorRight;
// get edges of
if (mSelectionOffset > 0 && mSelectedPosition < getChildCount() - 1) {
View leftView = getChildAt(mSelectedPosition);
View rightView = getChildAt(mSelectedPosition + 1);
left = leftView.getLeft() + mIndicatorMarginLeft;
right = rightView.getRight() - mIndicatorMarginRight;
}
// ensure color updated
if (mSelectedIndicatorPaint.getShader() == null || mIsColorDirty) {
LinearGradient gradient = new LinearGradient(0, 0, getWidth(), 0, mStartColor, mEndColor, Shader.TileMode.CLAMP);
mSelectedIndicatorPaint.setShader(gradient);
}
// visible rect
mIndicatorRect.set(mIndicatorLeft, getHeight() - mSelectedIndicatorHeight - mIndicatorMarginBottom,
mIndicatorRight, getHeight() - mIndicatorMarginBottom);
// show dst round rect only, but with src background
int sc = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);
// draw dst round rect
canvas.drawRoundRect(mIndicatorRect, mSelectedIndicatorHeight / 2, mSelectedIndicatorHeight / 2, mSelectedIndicatorPaint);
mSelectedIndicatorPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
// draw src background on
canvas.drawRect(left, getHeight() - mSelectedIndicatorHeight - mIndicatorMarginBottom,
right, getHeight() - mIndicatorMarginBottom, mSelectedIndicatorPaint);
mSelectedIndicatorPaint.setXfermode(null);
canvas.restoreToCount(sc);
}
}
private static ColorStateList createColorStateList(int defaultColor, int selectedColor) {
final int[][] states = new int[2][];
final int[] colors = new int[2];
int i = 0;
states[i] = SELECTED_STATE_SET;
colors[i] = selectedColor;
i++;
// Default enabled state
states[i] = EMPTY_STATE_SET;
colors[i] = defaultColor;
i++;
return new ColorStateList(states, colors);
}
private int getDefaultHeight() {
boolean hasIconAndText = false;
for (int i = 0, count = mTabs.size(); i < count; i++) {
Tab tab = mTabs.get(i);
if (tab != null && tab.getIcon() != null && !TextUtils.isEmpty(tab.getText())) {
hasIconAndText = true;
break;
}
}
return hasIconAndText ? DEFAULT_HEIGHT_WITH_TEXT_ICON : DEFAULT_HEIGHT;
}
private int getTabMinWidth() {
if (mRequestedTabMinWidth != INVALID_WIDTH) {
// If we have been given a min width, use it
return mRequestedTabMinWidth;
}
// Else, we'll use the default value
return mMode == MODE_SCROLLABLE ? mScrollableTabMinWidth : 0;
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
// We don't care about the layout params of any views added to us, since we don't actually
// add them. The only view we add is the SlidingTabStrip, which is done manually.
// We return the default layout params so that we don't blow up if we're given a TabItem
// without android:layout_* values.
return generateDefaultLayoutParams();
}
int getTabMaxWidth() {
return mTabMaxWidth;
}
/**
* A {@link ViewPager.OnPageChangeListener} class which contains the
* necessary calls back to the provided {@link TabLayout} so that the tab position is
* kept in sync.
*
* <p>This class stores the provided TabLayout weakly, meaning that you can use
* {@link ViewPager#addOnPageChangeListener(ViewPager.OnPageChangeListener)
* addOnPageChangeListener(OnPageChangeListener)} without removing the listener and
* not cause a leak.
*/
public static class TabLayoutOnPageChangeListener implements ViewPager.OnPageChangeListener {
private final WeakReference<TabLayout> mTabLayoutRef;
private int mPreviousScrollState;
private int mScrollState;
public TabLayoutOnPageChangeListener(TabLayout tabLayout) {
mTabLayoutRef = new WeakReference<>(tabLayout);
}
@Override
public void onPageScrollStateChanged(final int state) {
mPreviousScrollState = mScrollState;
mScrollState = state;
}
@Override
public void onPageScrolled(final int position, final float positionOffset,
final int positionOffsetPixels) {
final TabLayout tabLayout = mTabLayoutRef.get();
if (tabLayout != null) {
// Only update the text selection if we're not settling, or we are settling after
// being dragged
final boolean updateText = mScrollState != SCROLL_STATE_SETTLING ||
mPreviousScrollState == SCROLL_STATE_DRAGGING;
// Update the indicator if we're not settling after being idle. This is caused
// from a setCurrentItem() call and will be handled by an animation from
// onPageSelected() instead.
final boolean updateIndicator = !(mScrollState == SCROLL_STATE_SETTLING
&& mPreviousScrollState == SCROLL_STATE_IDLE);
tabLayout.setScrollPosition(position, positionOffset, updateText, updateIndicator);
}
}
@Override
public void onPageSelected(final int position) {
final TabLayout tabLayout = mTabLayoutRef.get();
if (tabLayout != null && tabLayout.getSelectedTabPosition() != position
&& position < tabLayout.getTabCount()) {
// Select the tab, only updating the indicator if we're not being dragged/settled
// (since onPageScrolled will handle that).
final boolean updateIndicator = mScrollState == SCROLL_STATE_IDLE
|| (mScrollState == SCROLL_STATE_SETTLING
&& mPreviousScrollState == SCROLL_STATE_IDLE);
tabLayout.selectTab(tabLayout.getTabAt(position), updateIndicator);
}
}
void reset() {
mPreviousScrollState = mScrollState = SCROLL_STATE_IDLE;
}
}
/**
* A {@link TabLayout.OnTabSelectedListener} class which contains the necessary calls back
* to the provided {@link ViewPager} so that the tab position is kept in sync.
*/
public static class ViewPagerOnTabSelectedListener implements TabLayout.OnTabSelectedListener {
private final ViewPager mViewPager;
public ViewPagerOnTabSelectedListener(ViewPager viewPager) {
mViewPager = viewPager;
}
@Override
public void onTabSelected(TabLayout.Tab tab) {
mViewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
// No-op
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
// No-op
}
}
private class PagerAdapterObserver extends DataSetObserver {
PagerAdapterObserver() {
}
@Override
public void onChanged() {
populateFromPagerAdapter();
}
@Override
public void onInvalidated() {
populateFromPagerAdapter();
}
}
private class AdapterChangeListener implements ViewPager.OnAdapterChangeListener {
private boolean mAutoRefresh;
AdapterChangeListener() {
}
@Override
public void onAdapterChanged(@NonNull ViewPager viewPager,
@Nullable PagerAdapter oldAdapter, @Nullable PagerAdapter newAdapter) {
if (mViewPager == viewPager) {
setPagerAdapter(newAdapter, mAutoRefresh);
}
}
void setAutoRefresh(boolean autoRefresh) {
mAutoRefresh = autoRefresh;
}
}
}
\ No newline at end of file
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mints.goodmoney.ui.widgets.tablayout;
import android.content.Context;
import android.content.res.TypedArray;
class ThemeUtils {
private static final int[] APPCOMPAT_CHECK_ATTRS = {
androidx.appcompat.R.attr.colorPrimary
};
static void checkAppCompatTheme(Context context) {
TypedArray a = context.obtainStyledAttributes(APPCOMPAT_CHECK_ATTRS);
final boolean failed = !a.hasValue(0);
if (a != null) {
a.recycle();
}
if (failed) {
throw new IllegalArgumentException("You need to use a Theme.AppCompat theme "
+ "(or descendant) with the design library.");
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/item_rb_selector_left_selected" android:state_checked="true" />
<item android:drawable="@drawable/item_rb_selector_left_unselected" android:state_checked="false" />
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/blue" />
<corners
android:bottomLeftRadius="10dp"
android:topLeftRadius="10dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<corners
android:bottomLeftRadius="10dp"
android:topLeftRadius="10dp" />
<padding android:right="-1dp" />
<stroke
android:width="1dp"
android:color="@color/blue" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/item_rb_selector_right_selected" android:state_checked="true" />
<item android:drawable="@drawable/item_rb_selector_right_unselected" android:state_checked="false" />
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/blue" />
<corners
android:bottomRightRadius="10dp"
android:topRightRadius="10dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<corners
android:bottomRightRadius="10dp"
android:topRightRadius="10dp" />
<padding android:left="-1dp" />
<stroke
android:width="1dp"
android:color="@color/blue" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/blue" android:state_checked="false" />
<item android:color="@color/white" android:state_checked="true" />
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#ffff9837" />
<corners android:radius="25dp" />
<gradient
android:angle="180"
android:endColor="#ffff7f2c"
android:startColor="#ffffb032"
android:type="linear"
android:useLevel="true" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- 填充的颜色 -->
<solid android:color="#FFFFFF" />
<!-- 设置按钮的四个角为弧形 -->
<!-- android:radius 弧形的半径 -->
<corners android:radius="8dip" />
<solid android:color="#ffffffff" />
<corners android:radius="15dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- 填充的颜色 -->
<solid android:color="@color/grayc" />
<!-- 设置按钮的四个角为弧形 -->
<!-- android:radius 弧形的半径 -->
<solid android:color="@color/white" />
<corners android:radius="20dip" />
<stroke
android:width="1dp"
android:color="@color/main_bg_text" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="270"
android:endColor="#ffff7f2c"
android:startColor="#ffffb032"
android:type="linear"
android:useLevel="true" />
<corners android:radius="2dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/icon_invite_hl" android:state_selected="true" />
<item android:drawable="@mipmap/icon_invite_hl_nor" />
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/icon_bro_hl" android:state_selected="true" />
<item android:drawable="@mipmap/icon_my_hl_nor" />
<item android:drawable="@mipmap/icon_home_hl" android:state_selected="true" />
<item android:drawable="@mipmap/icon_home_hl_nor" />
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/icon_pan_hl" android:state_selected="true" />
<item android:drawable="@mipmap/icon_pan_hl_nor" />
</selector>
\ No newline at end of file
......@@ -61,7 +61,7 @@
android:id="@+id/tab_iv_pan"
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/tab_my_btn" />
android:src="@drawable/tab_pan_btn" />
<TextView
android:id="@+id/tab_tv_pan"
......@@ -84,7 +84,7 @@
android:id="@+id/tab_iv_friends"
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/tab_my_btn" />
android:src="@drawable/tab_invite_btn" />
<TextView
android:id="@+id/tab_tv_friends"
......
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/header_layout" />
<include
android:id="@+id/item_phone"
layout="@layout/item_settings" />
<include
android:id="@+id/item_wechat"
layout="@layout/item_settings" />
<include
android:id="@+id/item_invitedCode"
layout="@layout/item_settings" />
<include
android:id="@+id/item_cleanCache"
layout="@layout/item_settings" />
<include
android:id="@+id/item_userAgree"
layout="@layout/item_settings" />
<include
android:id="@+id/item_privacyAgree"
layout="@layout/item_settings" />
<include
android:id="@+id/item_aboutUs"
layout="@layout/item_settings" />
<Button
android:id="@+id/btn_switch"
android:layout_width="201dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:layout_marginRight="20dp"
android:background="@drawable/shape_btn_switch"
android:text="切换账号"
android:textColor="@color/white"
android:textSize="16sp" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/tv_activity_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="20dp"
android:paddingTop="36dp"
android:paddingRight="14dp"
android:scaleType="center"
android:src="@mipmap/ic_activity_arrow" />
<ImageView
android:id="@+id/iv_activity_quit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingTop="36dp"
android:paddingRight="20dp"
android:scaleType="center"
android:src="@mipmap/ic_activity_quit" />
</LinearLayout>
android:layout_height="50dp"
android:layout_marginTop="20dp">
<ImageView
android:id="@+id/tv_activity_back"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerVertical="true"
android:padding="10dp"
android:src="@mipmap/ic_arrow_back" />
<ImageView
android:id="@+id/iv_activity_quit"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/tv_activity_back"
android:padding="12dp"
android:src="@mipmap/ic_close" />
<TextView
android:id="@+id/tv_activity_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="40dp"
android:layout_centerInParent="true"
android:textColor="@color/product_net_text"
android:textSize="14sp" />
android:textSize="16sp" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_alignParentBottom="true"
android:background="@color/my_color_gray" />
</RelativeLayout>
<ProgressBar
......@@ -56,7 +51,6 @@
android:max="100"
android:progressDrawable="@drawable/progress_bar_horizontal" />
<com.mints.library.widgets.BrowserLayout
android:id="@+id/browser_layout"
android:layout_width="match_parent"
......
......@@ -3,14 +3,15 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="30dp"
android:background="@color/white"
android:gravity="center">
<TextView
android:id="@+id/dialog_tv_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="-6dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="-6dp"
android:ellipsize="marquee"
android:gravity="center"
android:singleLine="true"
......
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:text="friends"
<include layout="@layout/header_layout" />
<com.scwang.smartrefresh.layout.SmartRefreshLayout
android:id="@+id/srl_my"
android:layout_width="match_parent"
android:layout_height="100dp"></Button>
</RelativeLayout>
android:layout_height="match_parent"
app:srlAccentColor="@color/gray"
app:srlPrimaryColor="@color/white">
<com.scwang.smartrefresh.layout.header.ClassicsHeader
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
app:layout_behavior=".ui.widgets.FlingBehavior">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsingToolbarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include
android:id="@+id/view_title1"
layout="@layout/view_title" />
<com.mints.goodmoney.ui.widgets.BannerView
android:id="@+id/bv_friends_task"
android:layout_width="match_parent"
android:layout_height="120dp"
app:bannerAnimDuration="1500"
app:bannerAnimScroll="true"
app:bannerAutoScroll="true"
app:bannerPageAlpha="0"
app:bannerPageMargin="8dp"
app:bannerPagePercent="0.9"
app:bannerPageScale="0.8"
app:bannerScrollDuration="4000" />
<com.mints.goodmoney.ui.widgets.BannerView
android:id="@+id/bv_friends_banner"
android:layout_width="match_parent"
android:layout_height="120dp"
app:bannerAnimDuration="1500"
app:bannerAnimScroll="true"
app:bannerAutoScroll="true"
app:bannerPageAlpha="0"
app:bannerPageMargin="8dp"
app:bannerPagePercent="0.9"
app:bannerPageScale="0.8"
app:bannerScrollDuration="4000" />
<include
android:id="@+id/view_title2"
layout="@layout/view_title" />
</LinearLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout>
<com.mints.goodmoney.ui.widgets.tablayout.TabLayout
android:id="@+id/tab_friends"
android:layout_width="wrap_content"
android:layout_height="56dp"
android:layout_gravity="center_horizontal"
app:indicatorEndColor="#e73820"
app:indicatorMarginBottom="3dp"
app:indicatorMarginEnd="22dp"
app:indicatorMarginStart="22dp"
app:indicatorStartColor="#d6694e"
app:tabIndicatorHeight="4dp"
app:tabMode="scrollable" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recy_friends"
android:layout_width="match_parent"
android:layout_height="1000dp"
android:background="@color/blue"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</com.scwang.smartrefresh.layout.SmartRefreshLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<com.scwang.smartrefresh.layout.SmartRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/srl_my"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:srlAccentColor="@color/gray"
app:srlPrimaryColor="@color/white">
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="vertical">
<com.scwang.smartrefresh.layout.header.ClassicsHeader
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<include layout="@layout/header_layout" />
<androidx.core.widget.NestedScrollView
<com.scwang.smartrefresh.layout.SmartRefreshLayout
android:id="@+id/srl_my"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="match_parent"
android:background="@color/blue"
app:srlAccentColor="@color/gray"
app:srlPrimaryColor="@color/white">
<LinearLayout
<com.scwang.smartrefresh.layout.header.ClassicsHeader
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include layout="@layout/item_fragment_main_my_title" />
<include layout="@layout/item_fragment_main_my_clock" />
android:layout_height="wrap_content" />
<include layout="@layout/item_fragment_main_my_promotions" />
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recy_my"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="false"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
android:background="@color/white"
android:orientation="vertical">
<include layout="@layout/item_fragment_main_my_title" />
<include layout="@layout/item_fragment_main_my_clock" />
<include layout="@layout/item_divider_gray" />
<include layout="@layout/item_fragment_main_my_promotions" />
<include layout="@layout/item_divider_gray" />
<include layout="@layout/view_title" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recy_my"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:nestedScrollingEnabled="false"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
<include layout="@layout/item_fragment_main_my_bottom" />
<include layout="@layout/item_fragment_main_my_bottom" />
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.core.widget.NestedScrollView>
</com.scwang.smartrefresh.layout.SmartRefreshLayout>
</com.scwang.smartrefresh.layout.SmartRefreshLayout>
\ No newline at end of file
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="70dp"
android:paddingTop="20dp">
<ImageView
android:id="@+id/iv_left_icon"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="10dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/product_net_text"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/iv_right_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginEnd="10dp"
android:scaleType="center"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/my_color_gray"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/iv_right_icon" />
</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="wrap_content"
android:padding="10dp">
<ImageView
android:id="@+id/item_bv_friends_task_iv"
android:layout_width="60dp"
android:layout_height="60dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/item_bv_friends_task_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="任务1"
app:layout_constraintStart_toEndOf="@id/item_bv_friends_task_iv"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/item_bv_friends_task_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="邀请1名好友"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/item_bv_friends_task_iv" />
<Button
android:id="@+id/item_bv_friends_task_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="去邀请"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<View xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="10dp"
android:background="@color/my_color_gray3" />
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_my_sign"
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="@mipmap/bg_versus_top"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:layout_marginEnd="6dp"
android:background="@mipmap/bg_sign"
android:gravity="center_vertical"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center_horizontal"
android:layout_marginStart="20dp"
android:layout_marginTop="30dp"
android:layout_marginEnd="20dp"
android:background="@mipmap/bg_versus_sign">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/item_clock_sign"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/ic_sign_icon"
android:visibility="visible" />
<LinearLayout
<TextView
android:id="@+id/item_clock_signday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginTop="100dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/item_clock_sign"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/ic_versus_sign_icon"
android:visibility="visible" />
<TextView
android:id="@+id/item_clock_signday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginLeft="16pt" />
android:layout_gravity="bottom"
android:layout_marginStart="16pt" />
</LinearLayout>
<com.mints.goodmoney.ui.widgets.SignView
android:id="@+id/item_clock_signview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:visibility="visible" />
</RelativeLayout>
</LinearLayout>
<com.mints.goodmoney.ui.widgets.SignView
android:id="@+id/item_clock_signview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:visibility="visible" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_my_hot"
<com.mints.goodmoney.ui.widgets.ExpandableGridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/item_promotions_egv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="20dp"
android:background="@drawable/shape_my_about_write"
android:elevation="2dip"
android:orientation="vertical"
android:visibility="visible">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:text="热门活动"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<com.mints.goodmoney.ui.widgets.ExpandableGridView
android:id="@+id/item_promotions_egv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="16dp"
android:columnWidth="80dp"
android:divider="@null"
android:dividerHeight="10dp"
android:elevation="6dip"
android:listSelector="@color/full_transparent"
android:numColumns="4"
android:scrollbars="none"
android:stretchMode="spacingWidthUniform" />
</LinearLayout>
\ No newline at end of file
android:layout_marginTop="10dp"
android:layout_marginBottom="16dp"
android:columnWidth="80dp"
android:divider="@null"
android:dividerHeight="10dp"
android:elevation="6dip"
android:listSelector="@color/full_transparent"
android:numColumns="4"
android:scrollbars="none"
android:stretchMode="spacingWidthUniform" />
\ 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="match_parent"
android:layout_height="260dp"
android:background="@mipmap/bg_my_top"
android:layout_height="200dp"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="个人中心"
android:textColor="@color/white"
android:textSize="18sp" />
<ImageView
android:id="@+id/item_title_settings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:src="@mipmap/ic_my_account" />
</RelativeLayout>
<LinearLayout
android:id="@+id/ll_my_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal"
android:paddingStart="20dp">
android:layout_marginStart="15dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="15dp"
android:orientation="horizontal">
<com.mints.goodmoney.ui.widgets.CircleImageView
android:id="@+id/item_title_avatar"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_width="70dp"
android:layout_height="70dp"
android:src="@mipmap/ic_launcher" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="10dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
......@@ -53,8 +32,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="未登录"
android:textColor="@color/white"
android:textSize="16sp"
android:textColor="@color/black"
android:textSize="18sp"
android:textStyle="bold" />
<LinearLayout
......@@ -67,7 +46,7 @@
android:id="@+id/item_title_invitecode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textColor="@color/black"
android:textSize="14sp" />
<TextView
......@@ -81,130 +60,67 @@
android:paddingRight="12dp"
android:paddingBottom="2dp"
android:text="复制"
android:textColor="@color/white"
android:textColor="@color/main_bg_text"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
<ImageView
android:id="@+id/item_iv_settings"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center_vertical"
android:padding="10dp"
android:src="@mipmap/ic_arrow_more" />
<TextView
android:id="@+id/item_title_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:paddingLeft="38dp"
android:paddingTop="8dp"
android:paddingRight="38dp"
android:paddingBottom="8dp"
android:text="去登录"
android:textColor="@color/white"
android:textSize="12sp" />
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_marginLeft="20dp"
android:layout_height="80dp"
android:layout_marginStart="15dp"
android:layout_marginTop="20dp"
android:layout_marginRight="20dp"
android:background="@drawable/shape_my_about_write"
android:layout_marginEnd="15dp"
android:background="@drawable/shape_gold_card"
android:elevation="2dip"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/item_title_gold"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|top"
android:layout_marginTop="20dp"
android:text="金币兑换"
android:textColor="@color/product_text"
android:textSize="14sp" />
<TextView
android:id="@+id/item_title_gold_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:text="0.00"
android:textColor="@color/main_mints"
android:textSize="26sp" />
</FrameLayout>
</LinearLayout>
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="10dp"
android:paddingEnd="10dp">
<View
android:layout_width="2dp"
android:layout_height="match_parent"
android:layout_marginTop="26dp"
android:layout_marginBottom="26dp"
android:background="@color/line_color" />
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/ic_gold" />
<LinearLayout
android:id="@+id/item_title_cash"
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|top"
android:layout_marginTop="20dp"
android:text="零钱"
android:textColor="@color/product_text"
android:textSize="14sp" />
android:text="我的金币"
android:textColor="@color/black"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/item_title_cash_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:text="0.00"
android:textColor="@color/main_mints"
android:textSize="26sp" />
<TextView
android:id="@+id/item_title_gold_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="5434344"
android:textColor="@color/my_color_orange"
android:textSize="26sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginStart="48dp"
android:layout_marginTop="10dp"
android:background="@drawable/shape_my_red"
android:paddingLeft="10dp"
android:paddingTop="2dp"
android:paddingRight="10dp"
android:paddingBottom="2dp"
android:text="提现"
android:textColor="@color/white"
android:textSize="12sp" />
</FrameLayout>
</LinearLayout>
<Button
android:id="@+id/btn_withdraw"
android:layout_width="60dp"
android:layout_height="30dp"
android:layout_marginStart="10dp"
android:background="@drawable/shape_btn_switch"
android:text="提现"
android:textColor="@color/white"
android:textSize="16sp" />
</LinearLayout>
......
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/item_invited_tv_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1" />
<ImageView
android:id="@+id/item_invited_iv"
android:layout_width="60dp"
android:layout_height="60dp" />
<TextView
android:layout_weight="1"
android:id="@+id/item_invited_tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我的好友" />
<TextView
android:id="@+id/item_invited_tv_coin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="99999999金币" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="20dp">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:drawablePadding="10dp"
android:gravity="center_vertical"
android:textColor="@color/product_net_text"
android:textSize="16sp" />
<ImageView
android:id="@+id/iv_right"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:src="@mipmap/ic_arrow_more"
android:visibility="gone" />
<TextView
android:id="@+id/tv_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:visibility="gone" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_alignParentBottom="true"
android:background="@color/my_color_gray" />
</RelativeLayout>
\ No newline at end of file
......@@ -5,11 +5,11 @@
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="10pt"
android:layout_height="2dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="54pt"
android:layout_marginTop="-14pt"
android:layout_marginRight="54pt"
android:layout_marginStart="14dp"
android:layout_marginTop="-7dp"
android:layout_marginEnd="27dp"
android:background="@color/order_hint_color" />
<LinearLayout
......@@ -27,20 +27,20 @@
<TextView
android:id="@+id/tv_sign_first"
android:layout_width="50pt"
android:layout_height="50pt"
android:layout_width="25dp"
android:layout_height="25dp"
android:gravity="center"
android:textColor="@color/white"
android:textSize="@dimen/font_size_12" />
android:textSize="@dimen/font_size_14" />
<TextView
android:id="@+id/tv_sign_firstday"
android:layout_width="wrap_content"
android:layout_height="30pt"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="1天"
android:textColor="@color/black"
android:textSize="@dimen/font_size_10" />
android:textColor="@color/main_bg_text"
android:textSize="@dimen/font_size_12" />
</LinearLayout>
<LinearLayout
......@@ -53,20 +53,20 @@
<TextView
android:id="@+id/tv_sign_two"
android:layout_width="50pt"
android:layout_height="50pt"
android:layout_width="25dp"
android:layout_height="25dp"
android:gravity="center"
android:textColor="@color/white"
android:textSize="@dimen/font_size_12" />
android:textSize="@dimen/font_size_14" />
<TextView
android:id="@+id/tv_sign_twoday"
android:layout_width="wrap_content"
android:layout_height="30pt"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="2天"
android:textColor="@color/black"
android:textSize="@dimen/font_size_10" />
android:textColor="@color/main_bg_text"
android:textSize="@dimen/font_size_12" />
</LinearLayout>
<LinearLayout
......@@ -79,20 +79,20 @@
<TextView
android:id="@+id/tv_sign_three"
android:layout_width="50pt"
android:layout_height="50pt"
android:layout_width="25dp"
android:layout_height="25dp"
android:gravity="center"
android:textColor="@color/white"
android:textSize="@dimen/font_size_12" />
android:textSize="@dimen/font_size_14" />
<TextView
android:id="@+id/tv_sign_threeday"
android:layout_width="wrap_content"
android:layout_height="30pt"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="3天"
android:textColor="@color/black"
android:textSize="@dimen/font_size_10" />
android:textColor="@color/main_bg_text"
android:textSize="@dimen/font_size_12" />
</LinearLayout>
<LinearLayout
......@@ -105,20 +105,20 @@
<TextView
android:id="@+id/tv_sign_four"
android:layout_width="50pt"
android:layout_height="50pt"
android:layout_width="25dp"
android:layout_height="25dp"
android:gravity="center"
android:textColor="@color/white"
android:textSize="@dimen/font_size_12" />
android:textSize="@dimen/font_size_14" />
<TextView
android:id="@+id/tv_sign_fourday"
android:layout_width="wrap_content"
android:layout_height="30pt"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="4天"
android:textColor="@color/black"
android:textSize="@dimen/font_size_10" />
android:textColor="@color/main_bg_text"
android:textSize="@dimen/font_size_12" />
</LinearLayout>
<LinearLayout
......@@ -131,20 +131,20 @@
<TextView
android:id="@+id/tv_sign_five"
android:layout_width="50pt"
android:layout_height="50pt"
android:layout_width="25dp"
android:layout_height="25dp"
android:gravity="center"
android:textColor="@color/white"
android:textSize="@dimen/font_size_12" />
android:textSize="@dimen/font_size_14" />
<TextView
android:id="@+id/tv_sign_fiveday"
android:layout_width="wrap_content"
android:layout_height="30pt"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="5天"
android:textColor="@color/black"
android:textSize="@dimen/font_size_10" />
android:textColor="@color/main_bg_text"
android:textSize="@dimen/font_size_12" />
</LinearLayout>
<LinearLayout
......@@ -157,20 +157,20 @@
<TextView
android:id="@+id/tv_sign_six"
android:layout_width="50pt"
android:layout_height="50pt"
android:layout_width="25dp"
android:layout_height="25dp"
android:gravity="center"
android:textColor="@color/white"
android:textSize="@dimen/font_size_12" />
android:textSize="@dimen/font_size_14" />
<TextView
android:id="@+id/tv_sign_sixday"
android:layout_width="wrap_content"
android:layout_height="30pt"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="6天"
android:textColor="@color/black"
android:textSize="@dimen/font_size_10" />
android:textColor="@color/main_bg_text"
android:textSize="@dimen/font_size_12" />
</LinearLayout>
<LinearLayout
......@@ -183,21 +183,21 @@
<TextView
android:id="@+id/tv_sign_seven"
android:layout_width="50pt"
android:layout_height="50pt"
android:layout_width="25dp"
android:layout_height="25dp"
android:gravity="center"
android:text="78"
android:textColor="@color/white"
android:textSize="@dimen/font_size_12" />
android:textSize="@dimen/font_size_14" />
<TextView
android:id="@+id/tv_sign_sevenday"
android:layout_width="wrap_content"
android:layout_height="30pt"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="7天"
android:textColor="@color/black"
android:textSize="@dimen/font_size_10" />
android:textColor="@color/main_bg_text"
android:textSize="@dimen/font_size_12" />
</LinearLayout>
</LinearLayout>
......
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp">
<View
android:layout_width="5dp"
android:layout_height="16dp"
android:layout_centerVertical="true"
android:background="@drawable/shape_view_dot" />
<TextView
android:id="@+id/view_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="10dp"
android:textColor="@color/black"
android:textSize="18sp"
android:textStyle="bold" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_alignParentBottom="true"
android:background="@color/my_color_gray" />
</RelativeLayout>
\ No newline at end of file
......@@ -39,21 +39,21 @@
<!--时间轴样式布局-->
<declare-styleable name="TimeLineLayout">
<!--每行高度-->
<attr name="tll_height" format="dimension|reference"/>
<attr name="tll_height" format="dimension|reference" />
<!--文字大小-->
<attr name="tll_textSize" format="dimension|reference"/>
<attr name="tll_textSize" format="dimension|reference" />
<!--文字颜色-->
<attr name="tll_textColor" format="color|reference"/>
<attr name="tll_textColor" format="color|reference" />
<!--文字和时间轴间距-->
<attr name="tll_padding" format="dimension|reference"/>
<attr name="tll_padding" format="dimension|reference" />
<!--时间轴圆点颜色-->
<attr name="tll_dotColor" format="color|reference"/>
<attr name="tll_dotColor" format="color|reference" />
<!--时间轴圆点半径-->
<attr name="tll_dotRadius" format="dimension|reference"/>
<attr name="tll_dotRadius" format="dimension|reference" />
<!--时间线颜色-->
<attr name="tll_lineColor" format="color|reference"/>
<attr name="tll_lineColor" format="color|reference" />
<!--时间线宽度-->
<attr name="tll_lineWidth" format="dimension|reference"/>
<attr name="tll_lineWidth" format="dimension|reference" />
</declare-styleable>
......@@ -95,4 +95,13 @@
<enum name="bottom" value="4" />
</attr>
</declare-styleable>
<!-- TabLayout -->
<declare-styleable name="TabLayout">
<attr name="indicatorStartColor" format="color|reference" />
<attr name="indicatorEndColor" format="color|reference" />
<attr name="indicatorMarginStart" format="dimension|reference" />
<attr name="indicatorMarginEnd" format="dimension|reference" />
<attr name="indicatorMarginBottom" format="dimension|reference" />
</declare-styleable>
</resources>
\ No newline at end of file
......@@ -149,5 +149,8 @@
<color name="my_color_blue">#93B7D9</color>
<color name="my_color_gray">#E6E6E6</color>
<color name="my_color_gray2">#F9FAFB</color>
<color name="my_color_gray3">#F8F8F8</color>
<color name="my_color_black">#343C4F</color>
<color name="my_color_orange">#FB560C</color>
</resources>
\ No newline at end of file
<resources>
<style name="SwipeBackLayout">
<item name="edge_size">0dp</item>
</style>
......
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