NTP-71867 | Amc fund details revamp (#16660)
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2025 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.amc.fundbuy.adapters
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.navi.amc.databinding.ItemFundTagBinding
|
||||
import com.navi.amc.fundbuy.models.FundTagData
|
||||
import com.navi.design.textview.model.TextWithStyle
|
||||
import com.navi.design.utils.dpToPxInInt
|
||||
import com.navi.design.utils.getNaviDrawable
|
||||
import com.navi.design.utils.parseColorSafe
|
||||
import com.navi.design.utils.setSpannableString
|
||||
|
||||
class FundTagsAdapter : RecyclerView.Adapter<FundTagsAdapter.TagViewHolder>() {
|
||||
|
||||
private val pills = mutableListOf<FundTagData>()
|
||||
|
||||
fun updatePills(newPills: List<FundTagData>) {
|
||||
pills.clear()
|
||||
pills.addAll(newPills)
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TagViewHolder {
|
||||
val binding = ItemFundTagBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return TagViewHolder(binding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: TagViewHolder, position: Int) {
|
||||
holder.bind(pills[position])
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = pills.size
|
||||
|
||||
class TagViewHolder(private val binding: ItemFundTagBinding) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
|
||||
fun bind(pill: FundTagData) {
|
||||
binding.apply {
|
||||
tagText.setSpannableString(TextWithStyle(pill.text, pill.span))
|
||||
|
||||
root.background =
|
||||
getNaviDrawable(
|
||||
backgroundColor = pill.bgColor.parseColorSafe(),
|
||||
cornerRadius = dpToPxInInt(16),
|
||||
)
|
||||
|
||||
root.setPadding(dpToPxInInt(4), dpToPxInInt(2), dpToPxInInt(4), dpToPxInInt(2))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,12 +8,12 @@
|
||||
package com.navi.amc.fundbuy.fragments
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Rect
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewStub
|
||||
import android.widget.ImageView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updateLayoutParams
|
||||
@@ -34,14 +34,16 @@ import com.navi.amc.common.view.InformationView
|
||||
import com.navi.amc.compose.feature.ftue.model.FundSelectionData
|
||||
import com.navi.amc.databinding.DownloadDocumentLayoutBinding
|
||||
import com.navi.amc.databinding.FundDetailScreenLayoutBinding
|
||||
import com.navi.amc.databinding.FundManagerLayoutBinding
|
||||
import com.navi.amc.databinding.InvestUspLayoutBinding
|
||||
import com.navi.amc.fundbuy.models.AmcHeaderData
|
||||
import com.navi.amc.fundbuy.models.FundReturn
|
||||
import com.navi.amc.fundbuy.viewmodel.FundBuyFlowViewModel
|
||||
import com.navi.amc.fundbuy.viewmodel.FundDetailViewModel
|
||||
import com.navi.amc.fundbuy.views.FundDetailCarouselView
|
||||
import com.navi.amc.fundbuy.views.FundDetailView
|
||||
import com.navi.amc.fundbuy.views.FundGraphToolTipView
|
||||
import com.navi.amc.fundbuy.views.FundGraphView
|
||||
import com.navi.amc.fundbuy.views.FundManagerView
|
||||
import com.navi.amc.fundbuy.views.ListItemProgressView
|
||||
import com.navi.amc.navigator.NaviAmcDeeplinkNavigator
|
||||
import com.navi.amc.utils.AmcAnalytics
|
||||
@@ -64,7 +66,6 @@ import com.navi.base.model.Padding
|
||||
import com.navi.base.utils.isNotNull
|
||||
import com.navi.base.utils.isNull
|
||||
import com.navi.base.utils.orFalse
|
||||
import com.navi.base.utils.orTrue
|
||||
import com.navi.base.utils.orZero
|
||||
import com.navi.common.listeners.FragmentInterchangeListener
|
||||
import com.navi.common.listeners.HeaderInteractionListener
|
||||
@@ -148,27 +149,25 @@ class FundDetailsFragment : AmcBaseFragment(), FooterInteractionListener {
|
||||
viewModel.fundDetailScreenData.observe(viewLifecycleOwner) { fundDetailScreenData ->
|
||||
hideLoader()
|
||||
binding.apply {
|
||||
binding.fundOnscrollView.apply {
|
||||
left.setSpannableString(viewModel.fundReturn.value?.leftText)
|
||||
right.setSpannableString(viewModel.fundReturn.value?.rightText)
|
||||
root.visibility = View.GONE
|
||||
}
|
||||
|
||||
scroll.viewTreeObserver.addOnScrollChangedListener {
|
||||
val rect = Rect()
|
||||
scroll.getHitRect(rect)
|
||||
val view = binding.container.findViewWithTag<FundGraphView>("graph")?.getTitle()
|
||||
val returnView =
|
||||
binding.container
|
||||
.findViewWithTag<FundGraphView>("graph")
|
||||
?.getReturnDetailsView()
|
||||
if (
|
||||
!view?.getLocalVisibleRect(rect).orTrue() &&
|
||||
!returnView?.getLocalVisibleRect(rect).orTrue()
|
||||
) {
|
||||
binding.fundOnscrollView.apply {
|
||||
left.setSpannableString(viewModel.fundReturn.value?.leftText)
|
||||
right.setSpannableString(viewModel.fundReturn.value?.rightText)
|
||||
val scrollY = scroll.scrollY
|
||||
binding.fundOnscrollView.apply {
|
||||
left.setSpannableString(viewModel.fundReturn.value?.leftText)
|
||||
right.setSpannableString(viewModel.fundReturn.value?.rightText)
|
||||
|
||||
if (scrollY > 0) {
|
||||
if (left.isVisible && right.isVisible) {
|
||||
root.visibility = View.VISIBLE
|
||||
}
|
||||
} else {
|
||||
root.visibility = View.GONE
|
||||
}
|
||||
} else {
|
||||
binding.fundOnscrollView.root.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
scroll.updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||
@@ -249,7 +248,36 @@ class FundDetailsFragment : AmcBaseFragment(), FooterInteractionListener {
|
||||
|
||||
fundDetailScreenData?.content?.amcHeaderData?.let {
|
||||
viewModel.fundName = it.title?.text.orEmpty()
|
||||
binding.header.setProperties(it)
|
||||
binding.header.setProperties(
|
||||
AmcHeaderData(
|
||||
title = it.title,
|
||||
subtitle = it.subtitle,
|
||||
icon = it.icon,
|
||||
bgColor = it.bgColor,
|
||||
filter = it.filter,
|
||||
label = it.label,
|
||||
iconSize = it.iconSize,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fundDetailScreenData?.content?.amcHeaderData?.fundTags?.let { fundTags ->
|
||||
if (binding.fundTags.adapter == null) {
|
||||
val tagsAdapter = com.navi.amc.fundbuy.adapters.FundTagsAdapter()
|
||||
binding.fundTags.adapter = tagsAdapter
|
||||
binding.fundTags.layoutManager =
|
||||
androidx.recyclerview.widget.LinearLayoutManager(
|
||||
context,
|
||||
androidx.recyclerview.widget.LinearLayoutManager.HORIZONTAL,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
(binding.fundTags.adapter as? com.navi.amc.fundbuy.adapters.FundTagsAdapter)
|
||||
?.updatePills(fundTags)
|
||||
|
||||
binding.fundTags.visibility =
|
||||
if (fundTags.isNotEmpty()) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
binding.companies.isVisible =
|
||||
@@ -257,6 +285,7 @@ class FundDetailsFragment : AmcBaseFragment(), FooterInteractionListener {
|
||||
binding.companies.showWhenDataIsAvailable(it)
|
||||
true
|
||||
} ?: run { false }
|
||||
|
||||
container.apply {
|
||||
removeAllViews()
|
||||
val inflater = LayoutInflater.from(context)
|
||||
@@ -271,6 +300,7 @@ class FundDetailsFragment : AmcBaseFragment(), FooterInteractionListener {
|
||||
viewModel.chipIdToGraphDataMap[viewModel.selectedChipId]!!
|
||||
)
|
||||
} else FundGraphUiState.Loading
|
||||
|
||||
val view = FundGraphView(context)
|
||||
view.setProperties(
|
||||
data = fundDetailScreenData.content.fundGraphDetails,
|
||||
@@ -283,9 +313,58 @@ class FundDetailsFragment : AmcBaseFragment(), FooterInteractionListener {
|
||||
vmSelectedKey = viewModel.selectedChipId,
|
||||
setRadioAction = ::setSelectedRadio,
|
||||
vmSelectedRadio = viewModel.selectedRadio,
|
||||
fundInfoCards = fundDetailScreenData.content.fundInfoCards,
|
||||
)
|
||||
view.tag = "graph"
|
||||
view.setPadding(
|
||||
view.paddingLeft,
|
||||
view.paddingTop + dpToPxInInt(10),
|
||||
view.paddingRight,
|
||||
view.paddingBottom + dpToPxInInt(10),
|
||||
)
|
||||
addView(view)
|
||||
|
||||
val showGraphTextView = view.getShowGraphTextView()
|
||||
val showGraphIconView = view.getShowGraphIconView()
|
||||
val showGraphContainer = view.getShowGraphContainer()
|
||||
|
||||
fundDetailScreenData.content.fundGraphDetails.showGraphTag?.let {
|
||||
showGraphTag ->
|
||||
showGraphTextView.setSpannableString(showGraphTag.title)
|
||||
showGraphTextView.isVisible = true
|
||||
showGraphIconView.isVisible = true
|
||||
|
||||
val shouldShowGraph =
|
||||
fundDetailScreenData.content.fundGraphDetails.shouldShowGraph ==
|
||||
true
|
||||
viewModel.setIsGraphVisible(shouldShowGraph)
|
||||
|
||||
val chartComponent = view.findViewById<View>(R.id.chart)
|
||||
val xAxisLabel = view.findViewById<View>(R.id.x_axis_label)
|
||||
val clErrorLoader = view.findViewById<View>(R.id.cl_error_loader)
|
||||
|
||||
if (!shouldShowGraph) {
|
||||
chartComponent?.visibility = View.GONE
|
||||
xAxisLabel?.visibility = View.GONE
|
||||
clErrorLoader?.visibility = View.GONE
|
||||
|
||||
showGraphIconView.showWhenDataIsAvailable(
|
||||
showGraphTag.unSelectedIconCode
|
||||
)
|
||||
}
|
||||
|
||||
showGraphContainer.setOnClickListener {
|
||||
if (viewModel.isGraphVisible.value == true) {
|
||||
viewModel.setIsGraphVisible(false)
|
||||
} else {
|
||||
viewModel.setIsGraphVisible(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
?: run {
|
||||
showGraphTextView.isVisible = false
|
||||
showGraphIconView.isVisible = false
|
||||
}
|
||||
}
|
||||
|
||||
fundDetailScreenData?.content?.usp?.let {
|
||||
@@ -326,8 +405,7 @@ class FundDetailsFragment : AmcBaseFragment(), FooterInteractionListener {
|
||||
fundDetailScreenData?.content?.fundHoldingDetails?.let { data ->
|
||||
val view = ListItemProgressView(context)
|
||||
view.setProperties(data) {
|
||||
val bundle =
|
||||
Bundle().apply { putString(Constant.DATA, Gson().toJson(data)) }
|
||||
val bundle = Bundle().apply { putString(DATA, Gson().toJson(data)) }
|
||||
ListItemProgressBottomSheet.newInstance(bundle).let { bottomSheet ->
|
||||
safelyShowBottomSheet(
|
||||
bottomSheet,
|
||||
@@ -337,21 +415,11 @@ class FundDetailsFragment : AmcBaseFragment(), FooterInteractionListener {
|
||||
}
|
||||
addView(view)
|
||||
}
|
||||
fundDetailScreenData?.content?.fundManagerDetailData?.let {
|
||||
val childBinding =
|
||||
DataBindingUtil.inflate<FundManagerLayoutBinding>(
|
||||
inflater,
|
||||
R.layout.fund_manager_layout,
|
||||
container,
|
||||
false,
|
||||
)
|
||||
childBinding.apply {
|
||||
title.setSpannableString(it.title)
|
||||
name.setSpannableString(it.name)
|
||||
experience.setSpannableString(it.experience)
|
||||
icon.showWhenDataIsAvailable(it.profile)
|
||||
}
|
||||
addView(childBinding.root)
|
||||
fundDetailScreenData?.content?.fundManagerDetailData?.let { managerData ->
|
||||
val fundManagerView = FundManagerView(requireContext())
|
||||
|
||||
fundManagerView.setProperties(managerData)
|
||||
addView(fundManagerView)
|
||||
}
|
||||
fundDetailScreenData?.content?.documentData?.let {
|
||||
val childBinding =
|
||||
@@ -365,6 +433,11 @@ class FundDetailsFragment : AmcBaseFragment(), FooterInteractionListener {
|
||||
title.setSpannableString(it.title)
|
||||
subtitle.setSpannableString(it.subtitle)
|
||||
icon.showWhenDataIsAvailable(it.icon?.iconCode)
|
||||
subtitleLinearLayout.background =
|
||||
getNaviDrawable(
|
||||
backgroundColor = it.bgColor.parseColorSafe("#F5F5F5"),
|
||||
cornerRadius = dpToPxInInt(4),
|
||||
)
|
||||
touch.setOnClickListener { view ->
|
||||
it.icon?.downloadUrlList?.let { downloadUrlList ->
|
||||
downloadUrlList.forEach { downloadUrl ->
|
||||
@@ -393,6 +466,14 @@ class FundDetailsFragment : AmcBaseFragment(), FooterInteractionListener {
|
||||
view.updateRootViewTopPadding(
|
||||
Padding(startDp = 0f, topDp = 0f, endDp = 0f, bottomDp = 24f)
|
||||
)
|
||||
view
|
||||
.findViewById<NaviTextView>(R.id.compliance_text)
|
||||
.setSpannableString(fundDetailScreenData.content.regulatoryInfo?.title)
|
||||
view
|
||||
.findViewById<ImageView>(R.id.compliance_icon)
|
||||
.showWhenDataIsAvailable(
|
||||
fundDetailScreenData.content.regulatoryInfo?.iconCode
|
||||
)
|
||||
addView(view)
|
||||
}
|
||||
fundDetailScreenData?.footer?.backCta?.let {
|
||||
@@ -424,12 +505,66 @@ class FundDetailsFragment : AmcBaseFragment(), FooterInteractionListener {
|
||||
viewLifecycleOwner.lifecycleScope.launchWhenResumed {
|
||||
viewModel.fundGraphData.collect { graphUiState -> updateGraph(graphUiState) }
|
||||
}
|
||||
viewModel.isGraphVisible.observeNonNull(viewLifecycleOwner) { isVisible ->
|
||||
val graphView = binding.container.findViewWithTag<FundGraphView>("graph")
|
||||
|
||||
graphView?.let { view ->
|
||||
val chartComponent = view.findViewById<View>(R.id.chart)
|
||||
val xAxisLabel = view.findViewById<View>(R.id.x_axis_label)
|
||||
val chipGroup = view.findViewById<View>(R.id.chip_group)
|
||||
val clErrorLoader = view.findViewById<View>(R.id.cl_error_loader)
|
||||
|
||||
val chart =
|
||||
view.findViewById<com.github.mikephil.charting.charts.LineChart>(R.id.chart)
|
||||
val marker = chart?.marker as? FundGraphToolTipView
|
||||
marker?.updateVisibility(isVisible)
|
||||
|
||||
if (isVisible) {
|
||||
chartComponent?.visibility = View.VISIBLE
|
||||
xAxisLabel?.visibility = View.VISIBLE
|
||||
clErrorLoader?.visibility = View.GONE
|
||||
|
||||
chipGroup?.let { group ->
|
||||
val params = group.layoutParams as? ConstraintLayout.LayoutParams
|
||||
params?.let {
|
||||
it.topMargin = dpToPxInInt(317)
|
||||
group.layoutParams = it
|
||||
}
|
||||
}
|
||||
} else {
|
||||
chartComponent?.visibility = View.GONE
|
||||
xAxisLabel?.visibility = View.GONE
|
||||
clErrorLoader?.visibility = View.GONE
|
||||
|
||||
chipGroup?.let { group ->
|
||||
val params = group.layoutParams as? ConstraintLayout.LayoutParams
|
||||
params?.let {
|
||||
it.topMargin = dpToPxInInt(24)
|
||||
group.layoutParams = it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val showGraphIconView = view.getShowGraphIconView()
|
||||
val showGraphTag =
|
||||
viewModel.fundDetailScreenData.value?.content?.fundGraphDetails?.showGraphTag
|
||||
|
||||
if (isVisible) {
|
||||
showGraphIconView.showWhenDataIsAvailable(showGraphTag?.selectedIconCode)
|
||||
} else {
|
||||
showGraphIconView.showWhenDataIsAvailable(showGraphTag?.unSelectedIconCode)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateGraph(graphUiState: FundGraphUiState) {
|
||||
binding.container
|
||||
.findViewWithTag<FundGraphView>("graph")
|
||||
?.setProperties(
|
||||
val graphView = binding.container.findViewWithTag<FundGraphView>("graph")
|
||||
|
||||
val wasGraphVisible = viewModel.isGraphVisible.value ?: true
|
||||
|
||||
graphView?.let { view ->
|
||||
view.setProperties(
|
||||
data = viewModel.fundDetailScreenData.value?.content?.fundGraphDetails,
|
||||
graphUiState = graphUiState,
|
||||
fundInvestmentDetailData =
|
||||
@@ -441,6 +576,35 @@ class FundDetailsFragment : AmcBaseFragment(), FooterInteractionListener {
|
||||
setRadioAction = ::setSelectedRadio,
|
||||
vmSelectedRadio = viewModel.selectedRadio,
|
||||
)
|
||||
|
||||
if (!wasGraphVisible) {
|
||||
viewModel.setIsGraphVisible(false)
|
||||
|
||||
val chartComponent = view.findViewById<View>(R.id.chart)
|
||||
val xAxisLabel = view.findViewById<View>(R.id.x_axis_label)
|
||||
val clErrorLoader = view.findViewById<View>(R.id.cl_error_loader)
|
||||
|
||||
chartComponent?.visibility = View.GONE
|
||||
xAxisLabel?.visibility = View.GONE
|
||||
clErrorLoader?.visibility = View.GONE
|
||||
|
||||
val chipGroup = view.findViewById<View>(R.id.chip_group)
|
||||
chipGroup?.let { group ->
|
||||
val params = group.layoutParams as? ConstraintLayout.LayoutParams
|
||||
params?.let {
|
||||
it.topMargin = dpToPxInInt(24)
|
||||
group.layoutParams = it
|
||||
}
|
||||
}
|
||||
|
||||
val showGraphIconView = view.getShowGraphIconView()
|
||||
val showGraphTag =
|
||||
viewModel.fundDetailScreenData.value?.content?.fundGraphDetails?.showGraphTag
|
||||
showGraphTag?.unSelectedIconCode?.let { iconCode ->
|
||||
showGraphIconView.showWhenDataIsAvailable(iconCode)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun navigate(action: ActionData) {
|
||||
@@ -450,7 +614,7 @@ class FundDetailsFragment : AmcBaseFragment(), FooterInteractionListener {
|
||||
private fun onActionIconClick(actionData: ActionData) {
|
||||
val url = actionData?.url
|
||||
sendEvent(actionData?.metaData?.clickedData)
|
||||
if (url == Constant.SHOW_BOTTOMSHEET) {
|
||||
if (url == SHOW_BOTTOMSHEET) {
|
||||
val data = actionData.parameters?.getOrNull(0)?.value
|
||||
val key = actionData.parameters?.getOrNull(0)?.key
|
||||
val bundle = Bundle().apply { putString(Constant.DATA, data) }
|
||||
|
||||
@@ -7,14 +7,18 @@
|
||||
|
||||
package com.navi.amc.fundbuy.models
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.navi.amc.common.model.Footer
|
||||
import com.navi.amc.common.model.FundInvestmentDetailData
|
||||
import com.navi.amc.common.model.InformationCardData
|
||||
import com.navi.common.model.Header
|
||||
import com.navi.design.textview.model.NaviSpan
|
||||
import com.navi.design.textview.model.TextWithStyle
|
||||
import com.navi.naviwidgets.models.FundDetailData
|
||||
import com.navi.naviwidgets.models.response.amc.TagData
|
||||
import java.io.Serializable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
data class FundDetails(
|
||||
@SerializedName("header") val header: Header? = null,
|
||||
@@ -23,7 +27,7 @@ data class FundDetails(
|
||||
)
|
||||
|
||||
data class FundDetailScreenData(
|
||||
@SerializedName("fundHeader") val amcHeaderData: AmcHeaderData? = null,
|
||||
@SerializedName("fundHeader") val amcHeaderData: FundDetailsHeaderData? = null,
|
||||
@SerializedName("fundDetails") val fundDetailData: FundDetailData? = null,
|
||||
@SerializedName("fundManagerDetails") val fundManagerDetailData: FundManagerData? = null,
|
||||
@SerializedName("fundHoldingDetails") val fundHoldingDetails: ListItemProgressData? = null,
|
||||
@@ -36,11 +40,37 @@ data class FundDetailScreenData(
|
||||
@SerializedName("companiesLogo") val companiesLogo: String? = null,
|
||||
@SerializedName("usp") val usp: FundUspData? = null,
|
||||
@SerializedName("disclaimerData") val disclaimerData: InformationCardData? = null,
|
||||
@SerializedName("fundInfoCards") val fundInfoCards: FundInfoCardsData? = null,
|
||||
@SerializedName("fundInvestmentDetails")
|
||||
val fundInvestmentDetails: FundInvestmentDetailData? = null,
|
||||
@SerializedName("regulatoryInfo") val regulatoryInfo: RegulatoryInfoData? = null,
|
||||
)
|
||||
|
||||
@Parcelize
|
||||
data class FundDetailsHeaderData(
|
||||
@SerializedName("title") val title: TextWithStyle? = null,
|
||||
@SerializedName("subtitle", alternate = ["subTitle"]) val subtitle: TextWithStyle? = null,
|
||||
@SerializedName("filter") val filter: IconData? = null,
|
||||
@SerializedName("label") val label: LabelData? = null,
|
||||
@SerializedName("icon") val icon: ActionIcon? = null,
|
||||
@SerializedName("bgColor") val bgColor: String? = null,
|
||||
@SerializedName("iconSize") val iconSize: Double? = null,
|
||||
@SerializedName("fundTags") val fundTags: List<FundTagData>? = null,
|
||||
) : Parcelable
|
||||
|
||||
data class FundUspData(
|
||||
@SerializedName("title") val title: TextWithStyle? = null,
|
||||
@SerializedName("items") val items: List<SubItemData>? = null,
|
||||
)
|
||||
|
||||
@Parcelize
|
||||
data class FundTagData(
|
||||
@SerializedName("bgColor") val bgColor: String? = null,
|
||||
@SerializedName("text") var text: String? = null,
|
||||
@SerializedName("span") val span: List<NaviSpan>? = null,
|
||||
) : Serializable, Parcelable
|
||||
|
||||
data class RegulatoryInfoData(
|
||||
@SerializedName("title") val title: TextWithStyle? = null,
|
||||
@SerializedName("iconCode") val iconCode: String? = null,
|
||||
)
|
||||
|
||||
@@ -16,6 +16,8 @@ data class FundGraphDetails(
|
||||
@SerializedName("items") val items: List<FundGraphData>? = null,
|
||||
@SerializedName("fundDuration") val fundDuration: List<FundDuration>? = null,
|
||||
@SerializedName("graphBgColor") val graphBgColor: String? = null,
|
||||
@SerializedName("showGraphTag") val showGraphTag: ShowGraphTagData? = null,
|
||||
@SerializedName("shouldShowGraph") val shouldShowGraph: Boolean? = null,
|
||||
)
|
||||
|
||||
data class FundGraphData(
|
||||
@@ -80,3 +82,9 @@ data class XAxisLabelData(
|
||||
@SerializedName("mid") val mid: String? = null,
|
||||
@SerializedName("end") val end: String? = null,
|
||||
)
|
||||
|
||||
data class ShowGraphTagData(
|
||||
@SerializedName("title") val title: TextWithStyle? = null,
|
||||
@SerializedName("selectedIconCode") val selectedIconCode: String? = null,
|
||||
@SerializedName("unSelectedIconCode") val unSelectedIconCode: String? = null,
|
||||
)
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2025 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.amc.fundbuy.models
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.navi.design.textview.model.TextWithStyle
|
||||
|
||||
data class FundInfoCardsData(@SerializedName("items") val items: List<FundInfoCardItem>? = null)
|
||||
|
||||
data class FundInfoCardItem(
|
||||
@SerializedName("title") val title: TextWithStyle? = null,
|
||||
@SerializedName("subtitle") val subtitle: TextWithStyle? = null,
|
||||
@SerializedName("topTag") val topTag: String? = null,
|
||||
@SerializedName("bgColor") val bgColor: String? = null,
|
||||
)
|
||||
@@ -15,4 +15,8 @@ data class FundManagerData(
|
||||
@SerializedName("name") val name: TextWithStyle? = null,
|
||||
@SerializedName("experience") val experience: TextWithStyle? = null,
|
||||
@SerializedName("profile") val profile: String? = null,
|
||||
@SerializedName("isExpanded") val isExpanded: Boolean? = null,
|
||||
@SerializedName("rightChevronDown") val rightChevronDown: String? = null,
|
||||
@SerializedName("rightChevronUp") val rightChevronUp: String? = null,
|
||||
@SerializedName("assetsDetails") val assetDetails: TextWithStyle? = null,
|
||||
)
|
||||
|
||||
@@ -18,6 +18,9 @@ data class ListItemProgressData(
|
||||
@SerializedName("listData") val listData: List<ListData>? = null,
|
||||
@SerializedName("displayCount") val displayCount: Int? = null,
|
||||
@SerializedName("action") val action: ActionData? = null,
|
||||
@SerializedName("rightChevronDown") val rightChevronDown: String? = null,
|
||||
@SerializedName("rightChevronUp") val rightChevronUp: String? = null,
|
||||
@SerializedName("isExpanded") val isExpanded: Boolean? = null,
|
||||
)
|
||||
|
||||
data class ListData(
|
||||
|
||||
@@ -52,6 +52,14 @@ class FundDetailViewModel @Inject constructor(private val repository: FundDetail
|
||||
var fundName: String? = null
|
||||
var selectedRadio: String? = null
|
||||
|
||||
private val _isGraphVisible = MutableLiveData(true)
|
||||
val isGraphVisible: LiveData<Boolean>
|
||||
get() = _isGraphVisible
|
||||
|
||||
fun setIsGraphVisible(isVisible: Boolean) {
|
||||
_isGraphVisible.value = isVisible
|
||||
}
|
||||
|
||||
fun getFundScreenData(isin: String, source: String?, screenName: String) {
|
||||
viewModelScope.launch {
|
||||
val response =
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
package com.navi.amc.fundbuy.views
|
||||
|
||||
import android.animation.LayoutTransition
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
@@ -18,6 +19,8 @@ import com.navi.amc.R
|
||||
import com.navi.amc.common.model.InformationCardData
|
||||
import com.navi.amc.databinding.FundDetailItemLayoutBinding
|
||||
import com.navi.amc.databinding.FundDetailViewLayoutBinding
|
||||
import com.navi.amc.utils.toggleContentVisibility
|
||||
import com.navi.amc.utils.updateChevronImage
|
||||
import com.navi.base.model.ActionData
|
||||
import com.navi.base.utils.orZero
|
||||
import com.navi.design.utils.setSpannableString
|
||||
@@ -27,11 +30,37 @@ import com.navi.naviwidgets.models.FundDetailData
|
||||
class FundDetailView(context: Context, attributeSet: AttributeSet? = null) :
|
||||
LinearLayout(context, attributeSet) {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "FundDetailView"
|
||||
}
|
||||
|
||||
private val binding: FundDetailViewLayoutBinding
|
||||
private var isExpanded: Boolean = false
|
||||
|
||||
init {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
binding = DataBindingUtil.inflate(inflater, R.layout.fund_detail_view_layout, this, true)
|
||||
|
||||
this.layoutTransition =
|
||||
LayoutTransition().apply { setDuration(LayoutTransition.CHANGING, 300) }
|
||||
}
|
||||
|
||||
private fun setupAccordion(data: FundDetailData) {
|
||||
if (data.isExpanded != null) {
|
||||
binding.titleBar.setOnClickListener {
|
||||
isExpanded = !isExpanded
|
||||
toggleContentVisibility(
|
||||
isExpanded = isExpanded,
|
||||
content = binding.itemContainer,
|
||||
chevronImage = binding.chevronImage,
|
||||
)
|
||||
}
|
||||
updateChevronImage(
|
||||
isExpanded = isExpanded,
|
||||
chevronImage = binding.chevronImage,
|
||||
chevronDown = data.rightChevronDown,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun setProperties(
|
||||
@@ -40,8 +69,12 @@ class FundDetailView(context: Context, attributeSet: AttributeSet? = null) :
|
||||
action: ((ActionData) -> Unit)? = null,
|
||||
iconClickAction: ((ActionData) -> Unit)? = null,
|
||||
) {
|
||||
isExpanded = data.isExpanded ?: true
|
||||
binding.title.setSpannableString(data.title)
|
||||
setupAccordion(data)
|
||||
|
||||
binding.itemContainer.apply {
|
||||
removeAllViews()
|
||||
data.items?.forEachIndexed { index, itemData ->
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val childBinding: FundDetailItemLayoutBinding =
|
||||
@@ -78,5 +111,7 @@ class FundDetailView(context: Context, attributeSet: AttributeSet? = null) :
|
||||
addView(childBinding.root)
|
||||
}
|
||||
}
|
||||
|
||||
binding.itemContainer.visibility = if (isExpanded) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,109 +8,244 @@
|
||||
package com.navi.amc.fundbuy.views
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.core.view.isVisible
|
||||
import com.github.mikephil.charting.components.MarkerView
|
||||
import com.github.mikephil.charting.data.Entry
|
||||
import com.github.mikephil.charting.highlight.Highlight
|
||||
import com.github.mikephil.charting.utils.MPPointF
|
||||
import com.navi.amc.R
|
||||
import com.navi.amc.databinding.FundGraphToolTipDetailsLayoutBinding
|
||||
import com.navi.amc.utils.Constant.RUPEE_SYMBOL
|
||||
import com.navi.design.textview.model.NaviSpan
|
||||
import com.navi.design.utils.doAnimate
|
||||
import com.navi.design.utils.dpToPx
|
||||
import com.navi.design.utils.spannedText
|
||||
import com.navi.naviwidgets.R
|
||||
import timber.log.Timber
|
||||
|
||||
class FundGraphToolTipView(context: Context, layout: Int) : MarkerView(context, layout) {
|
||||
|
||||
private var uiScreenWidth = 0
|
||||
private var title: TextView? = null
|
||||
private var subtitle: TextView? = null
|
||||
private var circleIndicatorView: ImageView? = null
|
||||
private var pointerCircle: ImageView? = null
|
||||
private var tooltipDetailsView: View? = null
|
||||
private var tooltipBinding: FundGraphToolTipDetailsLayoutBinding? = null
|
||||
|
||||
private var verticalLineView: View? = null
|
||||
private var duplicatePointerCircle: ImageView? = null
|
||||
|
||||
private val TOP_GAP = dpToPx(4)
|
||||
private val BOTTOM_GAP = dpToPx(24)
|
||||
private var chartParent: ViewGroup? = null
|
||||
|
||||
init {
|
||||
title = findViewById(R.id.title)
|
||||
subtitle = findViewById(R.id.subtitle)
|
||||
circleIndicatorView = findViewById(R.id.scroll_indicator)
|
||||
uiScreenWidth = resources.displayMetrics.widthPixels
|
||||
pointerCircle = findViewById(R.id.pointer_circle)
|
||||
tooltipBinding = FundGraphToolTipDetailsLayoutBinding.inflate(LayoutInflater.from(context))
|
||||
tooltipDetailsView = tooltipBinding?.root
|
||||
tooltipDetailsView?.visibility = View.INVISIBLE
|
||||
}
|
||||
|
||||
private fun setupTooltipDetailsView() {
|
||||
if (tooltipDetailsView?.parent == null && chartView != null) {
|
||||
chartParent = chartView?.parent as? ViewGroup
|
||||
chartParent?.let { parent ->
|
||||
if (verticalLineView == null) {
|
||||
val lineInflater = LayoutInflater.from(context)
|
||||
verticalLineView =
|
||||
lineInflater.inflate(R.layout.vertical_dotted_line_layout, parent, false)
|
||||
|
||||
val lineLayoutParams =
|
||||
FrameLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
chartView?.height ?: ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
)
|
||||
|
||||
parent.addView(verticalLineView, lineLayoutParams)
|
||||
}
|
||||
|
||||
if (duplicatePointerCircle == null) {
|
||||
duplicatePointerCircle =
|
||||
ImageView(context).apply {
|
||||
layoutParams =
|
||||
FrameLayout.LayoutParams(dpToPx(14).toInt(), dpToPx(14).toInt())
|
||||
setImageResource(com.navi.naviwidgets.R.drawable.black_border_circle)
|
||||
elevation = dpToPx(4).toFloat()
|
||||
visibility = View.INVISIBLE
|
||||
}
|
||||
parent.addView(duplicatePointerCircle)
|
||||
}
|
||||
|
||||
val layoutParams =
|
||||
FrameLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
)
|
||||
parent.addView(tooltipDetailsView, layoutParams)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun refreshContent(e: Entry?, highlight: Highlight?) {
|
||||
try {
|
||||
var nav = RUPEE_SYMBOL.plus(e?.y.toString())
|
||||
val date = e?.data as? String
|
||||
val titleText = "NAV: $nav"
|
||||
title?.text =
|
||||
titleText.spannedText(
|
||||
setupTooltipDetailsView()
|
||||
|
||||
val nav = RUPEE_SYMBOL + (e?.y?.toString() ?: "0.0")
|
||||
val date = e?.data as? String
|
||||
val titleText = "NAV: $nav"
|
||||
|
||||
tooltipBinding?.title?.text =
|
||||
titleText.spannedText(
|
||||
context = context,
|
||||
span =
|
||||
listOf(
|
||||
NaviSpan(
|
||||
startSpan = 0,
|
||||
endSpan = 4,
|
||||
fontName = "NAVI_BODY_REGULAR",
|
||||
fontSize = 12.0,
|
||||
spanColor = "#6B6B6B",
|
||||
),
|
||||
NaviSpan(
|
||||
startSpan = 4,
|
||||
endSpan = titleText.length,
|
||||
fontName = "NAVI_BODY_DEMI_BOLD",
|
||||
fontSize = 12.0,
|
||||
spanColor = "#191919",
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
date?.let {
|
||||
tooltipBinding?.subtitle?.isVisible = true
|
||||
val subtitleText = "$date"
|
||||
tooltipBinding?.subtitle?.text =
|
||||
subtitleText.spannedText(
|
||||
context = context,
|
||||
span =
|
||||
listOf(
|
||||
NaviSpan(
|
||||
startSpan = 0,
|
||||
endSpan = 4,
|
||||
endSpan = subtitleText.length,
|
||||
fontName = "NAVI_BODY_REGULAR",
|
||||
fontSize = 12.0,
|
||||
spanColor = "#6B6B6B",
|
||||
),
|
||||
NaviSpan(
|
||||
startSpan = 4,
|
||||
endSpan = 25,
|
||||
fontName = "NAVI_BODY_DEMI_BOLD",
|
||||
fontSize = 12.0,
|
||||
spanColor = "#191919",
|
||||
),
|
||||
)
|
||||
),
|
||||
)
|
||||
date?.let {
|
||||
subtitle?.isVisible = true
|
||||
val subtitleText = "on $date"
|
||||
subtitle?.text =
|
||||
subtitleText.spannedText(
|
||||
context = context,
|
||||
span =
|
||||
listOf(
|
||||
NaviSpan(
|
||||
startSpan = 0,
|
||||
endSpan = 30,
|
||||
fontName = "NAVI_BODY_REGULAR",
|
||||
fontSize = 12.0,
|
||||
spanColor = "#191919",
|
||||
)
|
||||
),
|
||||
)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e)
|
||||
}
|
||||
} ?: run { tooltipBinding?.subtitle?.isVisible = false }
|
||||
|
||||
tooltipDetailsView?.visibility = View.VISIBLE
|
||||
super.refreshContent(e, highlight)
|
||||
}
|
||||
|
||||
override fun getOffsetForDrawingAtPoint(posX: Float, posY: Float): MPPointF {
|
||||
var offsetX = 0f
|
||||
val leftBound = posX - (width.toFloat() / 2)
|
||||
val rightBound = posX + (width.toFloat() / 2)
|
||||
val indicatorHeight = circleIndicatorView?.measuredHeight?.toFloat()
|
||||
val indicatorWidth = circleIndicatorView?.measuredWidth?.toFloat()
|
||||
val indicatorOffset = if (indicatorHeight != null) indicatorHeight / 2 else 0f
|
||||
val pointerOffsetX = -(pointerCircle?.width?.div(2) ?: 0).toFloat()
|
||||
val pointerOffsetY = -(pointerCircle?.height?.div(2) ?: 0).toFloat()
|
||||
|
||||
if (leftBound <= 0f) {
|
||||
offsetX = -dpToPx(6)
|
||||
if (indicatorWidth != null) {
|
||||
circleIndicatorView?.doAnimate(translationX = -(width.toFloat() / 2 - dpToPx(6)))
|
||||
offset.x = pointerOffsetX
|
||||
offset.y = pointerOffsetY
|
||||
|
||||
pointerCircle?.visibility = View.INVISIBLE
|
||||
|
||||
tooltipDetailsView?.let { tooltipView ->
|
||||
val tooltipWidth = tooltipView.width.toFloat()
|
||||
var tooltipX = chartView.left + posX - (tooltipWidth / 2)
|
||||
|
||||
val actualDataPointX = chartView.left + posX
|
||||
val actualDataPointY = chartView.top + posY
|
||||
|
||||
if (tooltipX < chartView.left + dpToPx(16)) {
|
||||
tooltipX = chartView.left.toFloat() + dpToPx(16)
|
||||
} else if (tooltipX + tooltipWidth > chartView.right - dpToPx(16)) {
|
||||
tooltipX = chartView.right.toFloat() - tooltipWidth - dpToPx(16)
|
||||
}
|
||||
} else if (rightBound > chartView.measuredWidth) {
|
||||
offsetX = -(width.toFloat() - dpToPx(6))
|
||||
if (indicatorWidth != null) {
|
||||
circleIndicatorView?.doAnimate(translationX = width.toFloat() / 2 - dpToPx(6))
|
||||
|
||||
duplicatePointerCircle?.let { duplicateCircle ->
|
||||
duplicateCircle.x = actualDataPointX - (duplicateCircle.width / 2)
|
||||
duplicateCircle.y = actualDataPointY - (duplicateCircle.height / 2)
|
||||
duplicateCircle.visibility = View.VISIBLE
|
||||
}
|
||||
} else {
|
||||
offsetX = (-(width / 2)).toFloat()
|
||||
circleIndicatorView?.doAnimate(translationX = 0f)
|
||||
|
||||
verticalLineView?.let { line ->
|
||||
val legendHeight = dpToPx(20)
|
||||
val chartAreaHeight = chartView.height - legendHeight
|
||||
|
||||
val layoutParams = line.layoutParams
|
||||
layoutParams.height = chartAreaHeight.toInt()
|
||||
|
||||
line.x = actualDataPointX - (line.width / 2)
|
||||
line.y = chartView.top.toFloat()
|
||||
|
||||
line.layoutParams = layoutParams
|
||||
|
||||
line.visibility = tooltipDetailsView?.visibility ?: View.INVISIBLE
|
||||
}
|
||||
|
||||
val tooltipHeight = tooltipView.height.toFloat()
|
||||
|
||||
val upperPosition = chartView.top.toFloat() + TOP_GAP
|
||||
val lowerPosition =
|
||||
(chartView.top + chartView.height).toFloat() - tooltipHeight - BOTTOM_GAP
|
||||
|
||||
val upperTooltipBottom = upperPosition + tooltipHeight
|
||||
|
||||
val pointerY = chartView.top + posY
|
||||
|
||||
val yPosition = if (pointerY < upperTooltipBottom) lowerPosition else upperPosition
|
||||
|
||||
tooltipView.x = tooltipX
|
||||
tooltipView.y = yPosition
|
||||
|
||||
tooltipView.visibility = View.VISIBLE
|
||||
verticalLineView?.visibility = View.VISIBLE
|
||||
|
||||
return offset
|
||||
}
|
||||
offset.x = offsetX
|
||||
offset.y = -(height.toFloat() - indicatorOffset - dpToPx(4))
|
||||
|
||||
return offset
|
||||
}
|
||||
|
||||
fun hideTooltip() {
|
||||
tooltipDetailsView?.visibility = View.INVISIBLE
|
||||
verticalLineView?.visibility = View.INVISIBLE
|
||||
duplicatePointerCircle?.visibility = View.INVISIBLE
|
||||
pointerCircle?.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
fun updateVisibility(visible: Boolean) {
|
||||
if (!visible) {
|
||||
hideTooltip()
|
||||
|
||||
val parent = tooltipDetailsView?.parent as? ViewGroup
|
||||
parent?.removeView(tooltipDetailsView)
|
||||
parent?.removeView(verticalLineView)
|
||||
parent?.removeView(duplicatePointerCircle)
|
||||
|
||||
verticalLineView = null
|
||||
duplicatePointerCircle = null
|
||||
|
||||
chartView?.highlightValues(null)
|
||||
} else {
|
||||
if (tooltipDetailsView?.parent == null && chartView != null) {
|
||||
setupTooltipDetailsView()
|
||||
}
|
||||
hideTooltip()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
cleanupTooltip()
|
||||
}
|
||||
|
||||
private fun cleanupTooltip() {
|
||||
val parent = tooltipDetailsView?.parent as? ViewGroup
|
||||
parent?.removeView(tooltipDetailsView)
|
||||
parent?.removeView(verticalLineView)
|
||||
parent?.removeView(duplicatePointerCircle)
|
||||
verticalLineView = null
|
||||
duplicatePointerCircle = null
|
||||
tooltipDetailsView = null
|
||||
tooltipBinding = null
|
||||
chartParent = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ package com.navi.amc.fundbuy.views
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.text.TextUtils
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
@@ -20,9 +21,11 @@ import android.view.ViewTreeObserver
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.graphics.toColorInt
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.children
|
||||
import androidx.core.view.forEach
|
||||
import androidx.core.view.isNotEmpty
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.transition.Fade
|
||||
@@ -42,6 +45,7 @@ import com.navi.amc.databinding.FundGraphLayoutBinding
|
||||
import com.navi.amc.fundbuy.models.FundDuration
|
||||
import com.navi.amc.fundbuy.models.FundGraphData
|
||||
import com.navi.amc.fundbuy.models.FundGraphDetails
|
||||
import com.navi.amc.fundbuy.models.FundInfoCardsData
|
||||
import com.navi.amc.fundbuy.models.FundReturn
|
||||
import com.navi.amc.fundbuy.models.ReturnsData
|
||||
import com.navi.amc.utils.ColorUtils
|
||||
@@ -53,6 +57,7 @@ import com.navi.base.model.ActionData
|
||||
import com.navi.base.utils.orFalse
|
||||
import com.navi.base.utils.orZero
|
||||
import com.navi.common.animation.fadeIn
|
||||
import com.navi.design.textview.NaviTextView
|
||||
import com.navi.design.textview.model.TextWithStyle
|
||||
import com.navi.design.utils.CornerRadius
|
||||
import com.navi.design.utils.dpToPxInInt
|
||||
@@ -78,12 +83,22 @@ class FundGraphView(context: Context, attributeSet: AttributeSet? = null) :
|
||||
private var setRadioAction: ((String) -> Unit)? = null
|
||||
private var fundDurationData: FundDuration? = null
|
||||
private var selectedId: Int = 0
|
||||
private var hasDisplayedFundInfoCards = false
|
||||
|
||||
private val toolTipMarkerView: FundGraphToolTipView by lazy {
|
||||
FundGraphToolTipView(context = context, R.layout.fund_graph_tool_tip_view_layout)
|
||||
}
|
||||
|
||||
init {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
binding = DataBindingUtil.inflate(inflater, R.layout.fund_graph_layout, this, true)
|
||||
layoutParams = LayoutParams(MATCH_PARENT, WRAP_CONTENT)
|
||||
|
||||
tag = "graph"
|
||||
binding.showGraphText.tag = "showGraphText"
|
||||
binding.showGraphIcon.tag = "showGraphIcon"
|
||||
binding.showGraphContainer.tag = "showGraphContainer"
|
||||
|
||||
binding.chipTooltipContent.radioGroup.setOnCheckedChangeListener { group, checkedId ->
|
||||
when (checkedId) {
|
||||
R.id.radio_option_one_time -> {
|
||||
@@ -107,6 +122,7 @@ class FundGraphView(context: Context, attributeSet: AttributeSet? = null) :
|
||||
vmSelectedKey: String? = null,
|
||||
setRadioAction: ((String) -> Unit)? = null,
|
||||
vmSelectedRadio: String? = null,
|
||||
fundInfoCards: FundInfoCardsData? = null,
|
||||
) {
|
||||
this.apiClickAction = apiClickAction
|
||||
this.setRadioAction = setRadioAction
|
||||
@@ -115,6 +131,8 @@ class FundGraphView(context: Context, attributeSet: AttributeSet? = null) :
|
||||
setFundGraphPillsData(data, vmSelectedKey)
|
||||
}
|
||||
|
||||
setFundInfoCardsData(fundInfoCards)
|
||||
|
||||
when (graphUiState) {
|
||||
is FundGraphUiState.Loading -> {
|
||||
showLoader()
|
||||
@@ -167,6 +185,92 @@ class FundGraphView(context: Context, attributeSet: AttributeSet? = null) :
|
||||
}
|
||||
}
|
||||
|
||||
private fun setFundInfoCardsData(fundInfoCards: FundInfoCardsData?) {
|
||||
val cardsContainer = binding.fundInfoCards
|
||||
|
||||
if (fundInfoCards == null || fundInfoCards.items.isNullOrEmpty()) {
|
||||
if (!hasDisplayedFundInfoCards) {
|
||||
cardsContainer.visibility = View.GONE
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (hasDisplayedFundInfoCards && cardsContainer.isVisible && cardsContainer.isNotEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
cardsContainer.visibility = View.VISIBLE
|
||||
|
||||
cardsContainer.removeAllViews()
|
||||
|
||||
val cardWeight = 1.0f / fundInfoCards.items.size
|
||||
|
||||
fundInfoCards.items.forEachIndexed { index, cardItem ->
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val cardView =
|
||||
inflater.inflate(R.layout.fund_info_card_item_layout, cardsContainer, false)
|
||||
|
||||
val layoutParams =
|
||||
LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT).apply {
|
||||
weight = cardWeight
|
||||
|
||||
val marginDp = dpToPxInInt(2)
|
||||
marginStart = marginDp
|
||||
marginEnd = marginDp
|
||||
}
|
||||
cardView.layoutParams = layoutParams
|
||||
|
||||
val title = cardView.findViewById<NaviTextView>(R.id.title)
|
||||
val subtitle = cardView.findViewById<NaviTextView>(R.id.subtitle)
|
||||
val infoTag = cardView.findViewById<ImageView>(R.id.info_tag)
|
||||
|
||||
cardItem.bgColor?.let { colorString ->
|
||||
cardView.setBackgroundColor(colorString.parseColorSafe())
|
||||
}
|
||||
|
||||
cardItem.title?.let { title.setSpannableString(it) }
|
||||
title.maxLines = 1
|
||||
title.ellipsize = TextUtils.TruncateAt.END
|
||||
|
||||
cardItem.subtitle?.let { subtitle.setSpannableString(it) }
|
||||
|
||||
cardItem.topTag?.let { infoTag.showWhenDataIsAvailable(it) }
|
||||
|
||||
if (index == 0) {
|
||||
cardView.background =
|
||||
getNaviDrawable(
|
||||
radii =
|
||||
CornerRadius(
|
||||
leftTop = dpToPxInInt(4).toFloat(),
|
||||
rightTop = 0f,
|
||||
leftBottom = dpToPxInInt(4).toFloat(),
|
||||
rightBottom = 0f,
|
||||
),
|
||||
backgroundColor = (cardItem.bgColor ?: COLOR_WHITE).toColorInt(),
|
||||
)
|
||||
}
|
||||
|
||||
if (index == fundInfoCards.items.size - 1) {
|
||||
cardView.background =
|
||||
getNaviDrawable(
|
||||
radii =
|
||||
CornerRadius(
|
||||
leftTop = 0f,
|
||||
rightTop = dpToPxInInt(4).toFloat(),
|
||||
leftBottom = 0f,
|
||||
rightBottom = dpToPxInInt(4).toFloat(),
|
||||
),
|
||||
backgroundColor = (cardItem.bgColor ?: COLOR_WHITE).toColorInt(),
|
||||
)
|
||||
}
|
||||
|
||||
cardsContainer.addView(cardView)
|
||||
}
|
||||
|
||||
cardsContainer.visibility = View.VISIBLE
|
||||
hasDisplayedFundInfoCards = true
|
||||
}
|
||||
|
||||
private fun setFundGraphPillsData(data: FundGraphDetails?, vmSelectedKey: String?) {
|
||||
isGraphPillUpdated = true
|
||||
chipIdToDataMap.clear()
|
||||
@@ -330,8 +434,6 @@ class FundGraphView(context: Context, attributeSet: AttributeSet? = null) :
|
||||
fillDrawable = gradientDrawable
|
||||
}
|
||||
|
||||
val toolTipMarkerView =
|
||||
FundGraphToolTipView(context = context, R.layout.fund_graph_tool_tip_view_layout)
|
||||
binding.chart.setOnChartValueSelectedListener(
|
||||
object : OnChartValueSelectedListener {
|
||||
override fun onValueSelected(e: Entry, h: Highlight?) {
|
||||
@@ -341,7 +443,9 @@ class FundGraphView(context: Context, attributeSet: AttributeSet? = null) :
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNothingSelected() {}
|
||||
override fun onNothingSelected() {
|
||||
toolTipMarkerView.hideTooltip()
|
||||
}
|
||||
}
|
||||
)
|
||||
val lineData = LineData(graphInitialize)
|
||||
@@ -417,6 +521,14 @@ class FundGraphView(context: Context, attributeSet: AttributeSet? = null) :
|
||||
}
|
||||
|
||||
private fun updateSelectedChips(group: ChipGroup, checkedIds: List<Int>) {
|
||||
toolTipMarkerView.hideTooltip()
|
||||
binding.chart.highlightValues(null)
|
||||
|
||||
if (binding.chart.data != null && binding.chart.data.entryCount > 0) {
|
||||
binding.chart.marker = null
|
||||
binding.chart.marker = toolTipMarkerView
|
||||
}
|
||||
|
||||
for (childView in group.children) {
|
||||
if (childView is Chip) {
|
||||
val childId = childView.id
|
||||
@@ -447,6 +559,18 @@ class FundGraphView(context: Context, attributeSet: AttributeSet? = null) :
|
||||
return binding.fundReturnDetails
|
||||
}
|
||||
|
||||
fun getShowGraphTextView(): NaviTextView {
|
||||
return binding.showGraphText
|
||||
}
|
||||
|
||||
fun getShowGraphIconView(): ImageView {
|
||||
return binding.showGraphIcon
|
||||
}
|
||||
|
||||
fun getShowGraphContainer(): LinearLayout {
|
||||
return binding.showGraphContainer
|
||||
}
|
||||
|
||||
private fun updateGraph(key: String) {
|
||||
selectedKey = key
|
||||
apiClickAction?.invoke(key, false)
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024-2025 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.amc.fundbuy.views
|
||||
|
||||
import android.animation.LayoutTransition
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import com.navi.amc.R
|
||||
import com.navi.amc.databinding.FundManagerLayoutBinding
|
||||
import com.navi.amc.fundbuy.models.FundManagerData
|
||||
import com.navi.amc.utils.toggleContentVisibility
|
||||
import com.navi.amc.utils.updateChevronImage
|
||||
import com.navi.design.utils.setSpannableString
|
||||
import com.navi.naviwidgets.extensions.showWhenDataIsAvailable
|
||||
|
||||
class FundManagerView(context: Context, attributeSet: AttributeSet? = null) :
|
||||
ConstraintLayout(context, attributeSet) {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "FundManagerView"
|
||||
}
|
||||
|
||||
private val binding: FundManagerLayoutBinding
|
||||
private var isExpanded: Boolean = true
|
||||
|
||||
init {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
binding = DataBindingUtil.inflate(inflater, R.layout.fund_manager_layout, this, true)
|
||||
|
||||
this.layoutTransition =
|
||||
LayoutTransition().apply { setDuration(LayoutTransition.CHANGING, 300) }
|
||||
}
|
||||
|
||||
private fun setupAccordion(data: FundManagerData) {
|
||||
if (data.isExpanded != null) {
|
||||
binding.titleContainer.setOnClickListener {
|
||||
isExpanded = !isExpanded
|
||||
toggleContentVisibility(
|
||||
isExpanded = isExpanded,
|
||||
content = binding.contentContainer,
|
||||
chevronImage = binding.chevron,
|
||||
)
|
||||
}
|
||||
|
||||
updateChevronImage(
|
||||
isExpanded = isExpanded,
|
||||
chevronImage = binding.chevron,
|
||||
chevronDown = data.rightChevronDown,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun setProperties(data: FundManagerData) {
|
||||
isExpanded = data.isExpanded ?: true
|
||||
|
||||
binding.apply {
|
||||
title.setSpannableString(data.title)
|
||||
|
||||
name.setSpannableString(data.name)
|
||||
experience.setSpannableString(data.experience)
|
||||
icon.showWhenDataIsAvailable(data.profile)
|
||||
assetDetails.setSpannableString(data.assetDetails)
|
||||
|
||||
contentContainer.visibility = if (isExpanded) View.VISIBLE else View.GONE
|
||||
|
||||
setupAccordion(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,11 @@
|
||||
|
||||
package com.navi.amc.fundbuy.views
|
||||
|
||||
import android.animation.LayoutTransition
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.view.View
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.databinding.DataBindingUtil
|
||||
@@ -18,6 +19,8 @@ import com.navi.amc.R
|
||||
import com.navi.amc.databinding.ListItemProgressBinding
|
||||
import com.navi.amc.fundbuy.adapters.ListItemProgressAdapter
|
||||
import com.navi.amc.fundbuy.models.ListItemProgressData
|
||||
import com.navi.amc.utils.toggleContentVisibility
|
||||
import com.navi.amc.utils.updateChevronImage
|
||||
import com.navi.base.utils.orZero
|
||||
import com.navi.design.R as DesignR
|
||||
import com.navi.design.utils.getNaviDrawable
|
||||
@@ -26,32 +29,61 @@ import com.navi.design.utils.setSpannableString
|
||||
|
||||
class ListItemProgressView(context: Context, attributeSet: AttributeSet? = null) :
|
||||
ConstraintLayout(context, attributeSet) {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "ListItemProgressView"
|
||||
}
|
||||
|
||||
private val binding: ListItemProgressBinding
|
||||
private val adapter = ListItemProgressAdapter()
|
||||
var expandState: Boolean = false
|
||||
private var expandListener: ((Boolean) -> Unit)? = null
|
||||
private var isExpanded: Boolean = true
|
||||
|
||||
init {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
binding = DataBindingUtil.inflate(inflater, R.layout.list_item_progress, this, true)
|
||||
layoutParams =
|
||||
ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
|
||||
this.layoutTransition =
|
||||
LayoutTransition().apply { setDuration(LayoutTransition.CHANGING, 300) }
|
||||
}
|
||||
|
||||
private fun setupAccordion(data: ListItemProgressData) {
|
||||
if (data.isExpanded != null) {
|
||||
binding.titleContainer.setOnClickListener {
|
||||
isExpanded = !isExpanded
|
||||
toggleContentVisibility(
|
||||
isExpanded = isExpanded,
|
||||
content = binding.contentContainer,
|
||||
chevronImage = binding.chevron,
|
||||
)
|
||||
}
|
||||
|
||||
updateChevronImage(
|
||||
isExpanded = isExpanded,
|
||||
chevronImage = binding.chevron,
|
||||
chevronDown = data.rightChevronDown,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun setProperties(data: ListItemProgressData, onClick: () -> Unit) {
|
||||
isExpanded = data.isExpanded ?: true
|
||||
|
||||
binding.apply {
|
||||
title.setSpannableString(data.title)
|
||||
leftTitle.setSpannableString(data.leftHeader)
|
||||
rightTitle.setSpannableString(data.rightHeader)
|
||||
|
||||
setupAccordion(data)
|
||||
|
||||
items.adapter =
|
||||
adapter.apply {
|
||||
data.listData?.let {
|
||||
data.displayCount?.let { count -> update(it.take(count)) }
|
||||
}
|
||||
}
|
||||
|
||||
contentContainer.visibility = if (isExpanded) View.VISIBLE else View.GONE
|
||||
|
||||
button.root.isVisible =
|
||||
if (data.listData?.size.orZero() > 3) {
|
||||
button.apply {
|
||||
@@ -63,10 +95,7 @@ class ListItemProgressView(context: Context, attributeSet: AttributeSet? = null)
|
||||
cornerRadius = resources.getDimension(DesignR.dimen.dp_4).toInt(),
|
||||
)
|
||||
}
|
||||
button.root.setOnClickListener {
|
||||
onClick.invoke()
|
||||
expandListener?.invoke(expandState)
|
||||
}
|
||||
button.root.setOnClickListener { onClick.invoke() }
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2025 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.amc.utils
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorListenerAdapter
|
||||
import android.animation.ValueAnimator
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import com.navi.naviwidgets.extensions.showWhenDataIsAvailable
|
||||
|
||||
fun expand(view: View) {
|
||||
view.measure(
|
||||
View.MeasureSpec.makeMeasureSpec((view.parent as View).width, View.MeasureSpec.EXACTLY),
|
||||
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
|
||||
)
|
||||
val targetHeight = view.measuredHeight
|
||||
|
||||
view.layoutParams.height = 0
|
||||
view.visibility = View.VISIBLE
|
||||
|
||||
val animator = ValueAnimator.ofInt(0, targetHeight)
|
||||
animator.addUpdateListener { valueAnimator ->
|
||||
val value = valueAnimator.animatedValue as Int
|
||||
view.layoutParams.height = value
|
||||
view.requestLayout()
|
||||
}
|
||||
animator.duration = 300
|
||||
animator.addListener(
|
||||
object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
view.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
}
|
||||
}
|
||||
)
|
||||
animator.start()
|
||||
}
|
||||
|
||||
fun collapse(view: View) {
|
||||
val initialHeight = view.measuredHeight
|
||||
val animator = ValueAnimator.ofInt(initialHeight, 0)
|
||||
animator.addUpdateListener { valueAnimator ->
|
||||
val value = valueAnimator.animatedValue as Int
|
||||
view.layoutParams.height = value
|
||||
view.requestLayout()
|
||||
}
|
||||
animator.duration = 300
|
||||
animator.addListener(
|
||||
object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
view.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
)
|
||||
animator.start()
|
||||
}
|
||||
|
||||
fun toggleContentVisibility(isExpanded: Boolean, content: View, chevronImage: ImageView) {
|
||||
if (isExpanded) {
|
||||
expand(content)
|
||||
} else {
|
||||
collapse(content)
|
||||
}
|
||||
chevronImage.animate().rotation(if (isExpanded) 180f else 0f).setDuration(300).start()
|
||||
}
|
||||
|
||||
fun updateChevronImage(isExpanded: Boolean, chevronImage: ImageView, chevronDown: String? = null) {
|
||||
chevronImage.showWhenDataIsAvailable(chevronDown)
|
||||
chevronImage.visibility = View.VISIBLE
|
||||
chevronImage.rotation = if (isExpanded) 180f else 0f
|
||||
}
|
||||
@@ -24,7 +24,7 @@ object ColorUtils {
|
||||
const val KEY_COLOR_NEGATIVE = "negative"
|
||||
const val DEFAULT_COLOR_VARIATION_SELECTED = "#22A940"
|
||||
const val DEFAULT_COLOR_VARIATION_UNSELECTED = "#E3E5E5"
|
||||
const val FUND_GRAPH_BG_START_GRADIENT_COLOR = "#64FFFCEC"
|
||||
const val FUND_GRAPH_BG_START_GRADIENT_COLOR = "#F9F9FA"
|
||||
const val FUND_GRAPH_BG_END_GRADIENT_COLOR = "#FFFFFF"
|
||||
const val FUND_GRAPH_CHIP_SELECTED_COLOR = "#1F002A"
|
||||
|
||||
|
||||
@@ -1,75 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<!-- Drop Shadow Stack -->
|
||||
<item>
|
||||
<shape>
|
||||
<padding
|
||||
android:bottom="2dp"
|
||||
android:left="1dp"
|
||||
android:right="1dp" />
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@color/white" />
|
||||
|
||||
<solid android:color="#00CCCCCC" />
|
||||
|
||||
<corners android:radius="4dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<padding
|
||||
android:bottom="2dp"
|
||||
android:left="1dp"
|
||||
android:right="1dp" />
|
||||
|
||||
<solid android:color="#10CCCCCC" />
|
||||
|
||||
<corners android:radius="4dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<padding
|
||||
android:bottom="2dp"
|
||||
android:left="1dp"
|
||||
android:right="1dp" />
|
||||
|
||||
<solid android:color="#20CCCCCC" />
|
||||
|
||||
<corners android:radius="4dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<padding
|
||||
android:bottom="2dp"
|
||||
android:left="1dp"
|
||||
android:right="1dp" />
|
||||
|
||||
<solid android:color="#30CCCCCC" />
|
||||
|
||||
<corners android:radius="4dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<padding
|
||||
android:bottom="2dp"
|
||||
android:left="1dp"
|
||||
android:right="1dp" />
|
||||
|
||||
<solid android:color="#50CCCCCC" />
|
||||
|
||||
<corners android:radius="4dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<!-- Background -->
|
||||
<item>
|
||||
<shape>
|
||||
<solid android:color="#F5F5F5" />
|
||||
<size
|
||||
android:width="117dp"
|
||||
android:height="48dp" />
|
||||
<corners android:radius="4dp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</layer-list>
|
||||
<corners android:radius="@dimen/_4dp" />
|
||||
<stroke
|
||||
android:width="@dimen/dp_1"
|
||||
android:color="@color/border_grey_color" />
|
||||
</shape>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#E8F5EB" />
|
||||
<corners android:radius="4dp" />
|
||||
</shape>
|
||||
@@ -7,8 +7,7 @@
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="@dimen/dp_16"
|
||||
android:paddingEnd="@dimen/dp_16">
|
||||
android:padding="@dimen/_16dp">
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/title"
|
||||
@@ -18,31 +17,45 @@
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Scheme Information and KIM" />
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/subtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dp_16"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/title"
|
||||
tools:text="Download documents" />
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/subtitle_linear_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="@dimen/dp_16"
|
||||
android:paddingVertical="@dimen/_12dp"
|
||||
android:paddingHorizontal="@dimen/_16dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/title">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="@dimen/dp_16"
|
||||
android:layout_height="@dimen/dp_16"
|
||||
android:layout_marginStart="@dimen/dp_8"
|
||||
app:layout_constraintBottom_toBottomOf="@id/subtitle"
|
||||
app:layout_constraintStart_toEndOf="@id/subtitle"
|
||||
app:layout_constraintTop_toTopOf="@id/subtitle" />
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/subtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
tools:text="Download documents" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="@dimen/dp_16"
|
||||
android:layout_height="@dimen/dp_16"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/touch"
|
||||
android:layout_width="@dimen/dp_0"
|
||||
android:layout_height="@dimen/dp_48"
|
||||
app:layout_constraintBottom_toBottomOf="@id/subtitle"
|
||||
app:layout_constraintEnd_toEndOf="@id/icon"
|
||||
app:layout_constraintStart_toStartOf="@id/subtitle"
|
||||
app:layout_constraintTop_toTopOf="@id/subtitle" />
|
||||
app:layout_constraintBottom_toBottomOf="@id/subtitle_linear_layout"
|
||||
app:layout_constraintEnd_toEndOf="@id/subtitle_linear_layout"
|
||||
app:layout_constraintStart_toStartOf="@id/subtitle_linear_layout"
|
||||
app:layout_constraintTop_toTopOf="@id/subtitle_linear_layout" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</layout>
|
||||
@@ -47,11 +47,24 @@
|
||||
app:layout_goneMarginTop="@dimen/dp_0"
|
||||
app:layout_constraintTop_toBottomOf="@id/tag_container"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/fund_tags"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@id/header"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:paddingHorizontal="@dimen/_16dp"
|
||||
android:orientation="horizontal"
|
||||
android:overScrollMode="never"
|
||||
android:visibility="gone" />
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/companies"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@id/header" />
|
||||
android:layout_marginTop="@dimen/_16dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/fund_tags" />
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/container"
|
||||
@@ -59,8 +72,8 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="@dimen/dp_16"
|
||||
android:layout_marginTop="@dimen/dp_16"
|
||||
app:divider="@drawable/divider_margin_32"
|
||||
android:paddingTop="@dimen/_16dp"
|
||||
app:divider="@drawable/divider_margin_4"
|
||||
app:showDividers="middle"
|
||||
app:layout_constraintTop_toBottomOf="@id/companies" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -9,20 +9,48 @@
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="@dimen/dp_16">
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
<!-- Title bar with chevron for accordion functionality -->
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/title_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:lineSpacingExtra="@dimen/dp_4"
|
||||
tools:text="Fund Overview" />
|
||||
android:background="@color/white"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:paddingVertical="@dimen/_20dp"
|
||||
android:minHeight="@dimen/_24dp">
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:lineSpacingExtra="@dimen/dp_4"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/chevron_image"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Fund Overview" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/chevron_image"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:contentDescription="Expand or collapse"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<!-- Content container that will be shown/hidden -->
|
||||
<LinearLayout
|
||||
android:id="@+id/item_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:divider="@drawable/divider_32"
|
||||
android:layout_marginTop="@dimen/dp_16"
|
||||
android:paddingBottom="@dimen/_20dp"
|
||||
android:showDividers="middle" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -30,6 +30,31 @@
|
||||
app:layout_constraintBottom_toBottomOf="@id/title"
|
||||
tools:text="+ 200.75%" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/showGraphContainer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/title"
|
||||
app:layout_constraintBottom_toBottomOf="@id/title">
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/showGraphText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dp_6"
|
||||
tools:text="Show graph" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/showGraphIcon"
|
||||
android:layout_width="@dimen/_16dp"
|
||||
android:layout_height="@dimen/_16dp"
|
||||
android:src="@drawable/ic_alert_error_red"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/fund_return_details"
|
||||
android:layout_width="match_parent"
|
||||
@@ -121,7 +146,7 @@
|
||||
app:layout_constraintBottom_toTopOf="@id/chip_group"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:background="#FFFCEC"
|
||||
android:background="#F9F9FA"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
@@ -168,7 +193,8 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:translationZ="@dimen/dp_8"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingTop="@dimen/dp_8"
|
||||
android:paddingTop="@dimen/_12dp"
|
||||
android:paddingBottom="@dimen/_16dp"
|
||||
android:layout_marginTop="317dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
@@ -220,6 +246,20 @@
|
||||
app:layout_constraintTop_toTopOf="@id/chip_group" />
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/fund_info_cards"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/_16dp"
|
||||
android:paddingBottom="@dimen/_20dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/chip_group"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="visible"/>
|
||||
|
||||
<com.navi.amc.common.view.FundInvestmentDetailsView
|
||||
android:id="@+id/fund_investment_details"
|
||||
android:layout_width="match_parent"
|
||||
@@ -229,6 +269,6 @@
|
||||
android:layout_marginTop="@dimen/_28dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/chip_tooltip_content" />
|
||||
app:layout_constraintTop_toBottomOf="@id/fund_info_cards" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</layout>
|
||||
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/fund_graph_tooltip_bg"
|
||||
android:padding="@dimen/_1dp"
|
||||
android:elevation="@dimen/_0dp">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/tooltip_card"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="@dimen/_6dp"
|
||||
android:paddingVertical="@dimen/_4dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textColor="#333333"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="NAV : ₹10.88" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/subtitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textColor="#666666"
|
||||
android:textSize="12sp"
|
||||
tools:text="9 Jun 2025" />
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</layout>
|
||||
@@ -1,70 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="@dimen/dp_6"
|
||||
android:paddingBottom="@dimen/dp_4">
|
||||
android:translationZ="@dimen/_1dp"
|
||||
android:elevation="@dimen/_1dp"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<View
|
||||
android:id="@+id/background"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:background="@drawable/fund_graph_tooltip_bg"
|
||||
android:layout_marginBottom="@dimen/dp_6"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/scroll_indicator"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/title" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="left"
|
||||
android:textSize="@dimen/sp_12"
|
||||
android:minWidth="@dimen/dp_90"
|
||||
android:paddingHorizontal="@dimen/dp_12"
|
||||
android:paddingTop="@dimen/dp_6"
|
||||
<ImageView
|
||||
android:id="@+id/pointer_circle"
|
||||
android:layout_width="14dp"
|
||||
android:layout_height="14dp"
|
||||
android:src="@drawable/black_border_circle"
|
||||
android:elevation="@dimen/_1dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="NAV: ₹2,345.34"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/subtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/sp_12"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
android:gravity="left"
|
||||
android:minWidth="@dimen/dp_90"
|
||||
android:paddingHorizontal="@dimen/dp_12"
|
||||
android:paddingBottom="@dimen/dp_4"
|
||||
app:layout_constraintEnd_toEndOf="@id/title"
|
||||
app:layout_constraintStart_toStartOf="@id/title"
|
||||
app:layout_constraintTop_toBottomOf="@id/title"
|
||||
tools:text="on 27 Sep 2023"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/scroll_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="@dimen/dp_6"
|
||||
android:src="@drawable/black_border_circle"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/subtitle" />
|
||||
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</layout>
|
||||
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="#F8F8FA"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:padding="@dimen/_16dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/info_tag"
|
||||
android:layout_width="@dimen/_36dp"
|
||||
android:layout_height="@dimen/_18dp"
|
||||
android:translationY="-25dp"
|
||||
android:translationZ="@dimen/_2dp"
|
||||
app:layout_constraintStart_toStartOf="@id/title"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="NAV (9 Jun)"
|
||||
tools:textColor="#6B6B6B" />
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/subtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/title"
|
||||
tools:text="₹10.88"
|
||||
tools:textColor="#191919" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -3,45 +3,85 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="@dimen/dp_16"
|
||||
android:paddingEnd="@dimen/dp_16">
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="@dimen/dp_48"
|
||||
android:layout_height="@dimen/dp_48"
|
||||
android:layout_marginTop="@dimen/dp_16"
|
||||
<!-- Title Container with Chevron (Clickable Area) -->
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/title_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/white"
|
||||
android:paddingHorizontal="@dimen/dp_16"
|
||||
android:paddingVertical="@dimen/_20dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/title" />
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Fund manager" />
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/chevron"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Fund Manager" />
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_16"
|
||||
app:layout_constraintStart_toEndOf="@id/icon"
|
||||
app:layout_constraintTop_toTopOf="@id/icon"
|
||||
tools:text="Mr Ashutosh" />
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/chevron"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/title"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/title"
|
||||
tools:src="@android:drawable/arrow_up_float" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/experience"
|
||||
android:layout_width="wrap_content"
|
||||
<!-- Content container that will be shown/hidden -->
|
||||
<LinearLayout
|
||||
android:id="@+id/content_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dp_2"
|
||||
app:layout_constraintStart_toStartOf="@id/name"
|
||||
app:layout_constraintTop_toBottomOf="@id/name"
|
||||
tools:text="5 years" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
android:paddingBottom="@dimen/_20dp"
|
||||
android:paddingHorizontal="@dimen/dp_16"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="@dimen/dp_48"
|
||||
android:layout_height="@dimen/dp_48" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginStart="@dimen/dp_16"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="Mr Ashutosh" />
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/experience"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dp_2"
|
||||
tools:text="5 years" />
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/asset_details"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dp_2"
|
||||
tools:text="Asset details with long text that might wrap to multiple lines and require proper width constraints" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</layout>
|
||||
@@ -15,7 +15,7 @@
|
||||
android:layout_width="@dimen/dp_24"
|
||||
android:layout_height="@dimen/dp_24"
|
||||
android:layout_marginStart="@dimen/dp_16"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="@id/sub_title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@drawable/refund_image" />
|
||||
@@ -85,5 +85,27 @@
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:tilt_direction="forward" />
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/compliance_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/_56dp"
|
||||
tools:text="Regulated by"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/sub_title"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/compliance_icon"
|
||||
android:layout_width="@dimen/_46dp"
|
||||
android:layout_height="@dimen/_20dp"
|
||||
android:layout_marginTop="@dimen/_8dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintTop_toBottomOf="@id/compliance_text"
|
||||
android:src="@drawable/navi_pay_sa_home_page_send_to_bank_or_upi_icon"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</layout>
|
||||
13
android/navi-amc/src/main/res/layout/item_fund_tag.xml
Normal file
13
android/navi-amc/src/main/res/layout/item_fund_tag.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/tag_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/_8dp"
|
||||
android:gravity="center"
|
||||
tools:text="Equity" />
|
||||
|
||||
</layout>
|
||||
@@ -3,59 +3,90 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/dp_16"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Fund Holdings - Sector" />
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/left_title"
|
||||
android:layout_width="@dimen/dp_0"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dp_24"
|
||||
android:layout_marginStart="@dimen/dp_16"
|
||||
app:layout_constraintEnd_toStartOf="@id/right_title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/title"
|
||||
tools:text="Sector" />
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/right_title"
|
||||
android:layout_width="@dimen/dp_0"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
app:layout_constraintStart_toEndOf="@id/left_title"
|
||||
app:layout_constraintTop_toTopOf="@id/left_title"
|
||||
android:gravity="right"
|
||||
tools:text="Allocation" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/items"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/title_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dp_16"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:background="@color/white"
|
||||
android:paddingVertical="@dimen/_20dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/left_title" />
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<include
|
||||
android:id="@+id/button"
|
||||
android:layout_width="wrap_content"
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/dp_16"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/chevron"
|
||||
tools:text="Fund Holdings - Sector" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/chevron"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/title"
|
||||
app:layout_constraintBottom_toBottomOf="@id/title"
|
||||
tools:src="@android:drawable/arrow_up_float" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/content_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
layout="@layout/amc_button"
|
||||
android:layout_marginHorizontal="@dimen/dp_16"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/items" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
android:paddingBottom="@dimen/_20dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dp_8"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/left_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginStart="@dimen/dp_16"
|
||||
tools:text="Sector" />
|
||||
|
||||
<com.navi.design.textview.NaviTextView
|
||||
android:id="@+id/right_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:gravity="right"
|
||||
tools:text="Allocation" />
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/items"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dp_16"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
|
||||
|
||||
<include
|
||||
android:id="@+id/button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
layout="@layout/amc_button"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginHorizontal="@dimen/dp_16"
|
||||
android:layout_marginTop="@dimen/dp_8" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</layout>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:elevation="@dimen/_0dp"
|
||||
android:clipChildren="false">
|
||||
|
||||
<View
|
||||
android:id="@+id/vertical_dotted_line"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:background="@drawable/dashed_line_2" />
|
||||
</FrameLayout>
|
||||
</layout>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:bottom="@dimen/dp_4"
|
||||
android:top="@dimen/dp_4">
|
||||
<shape android:shape="rectangle">
|
||||
<size
|
||||
android:width="@dimen/_1dp"
|
||||
android:height="@dimen/_1dp" />
|
||||
<solid android:color="@color/backgroundSecondaryColor" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
@@ -30,6 +30,9 @@ data class FundDetailsWidget(
|
||||
data class FundDetailData(
|
||||
@SerializedName("title") val title: TextWithStyle? = null,
|
||||
@SerializedName("items") val items: List<FundItemData>? = null,
|
||||
@SerializedName("rightChevronUp") val rightChevronUp: String? = null,
|
||||
@SerializedName("rightChevronDown") val rightChevronDown: String? = null,
|
||||
@SerializedName("isExpanded") val isExpanded: Boolean? = null,
|
||||
)
|
||||
|
||||
data class FundItemData(
|
||||
|
||||
Reference in New Issue
Block a user