I appreciate the title is not very well written but its a little difficult to explain my issue succinctly...
I'm creating an Android app and I've got a custom chart view that has a little popup that should be able go outside the bounds of the chart view itself and will position itself based on where you select on the line chart.
I'm having trouble getting this to work when I have more than 1 parent view group in the hierarchy. This is my layout xml:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false">
<androidx.cardview.widget.CardView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.myapp.ui.views.chart.line.LineChartView
android:id="@+id/lineChartView"
android:layout_width="match_parent"
android:layout_height="228dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
if I remove the CardView so there is just the ConstraintLayout as the parent, it works. If I make the CardView bigger in the Y direction it allows enough space to draw the popup on the extra card space. But as it like this, it doesnt work.
It's kind of like it only allows you to draw up the hierarchy once onto the parent but not again onto the grandparent view.
How do I allow it to draw over the top of any and all parent views so its like a true "popup"?
Hope that makes sense
Simple answer: You can't draw outside the view's bounds.
<RelativeLayout>
<RelativeLayout
android:width="400dp"
android:height="400dp">
<LineChartView
android:width="100dp"
android:height="100dp"/>
<RelativeLayout>
</RelativeLayout>
In the above case, if you check the Canvas
size in LineChartView
's onDraw(canvas)
, you will find the height and width are 100dp. And that is the size of your View. So you can draw only within that space. The parent of your View doesn't really have any impact, unless you set your View's width/height as a dynamic value like MatchParent or WrapContent. If you do MatchParent on your View, then the width/height of the Canvas becomes 400dp.
In essence, the size of the Canvas determines what space is available to draw and what is visible on screen. To solve your use case, you could make you LineChartView
fill the entire screen. But with this approach, you will have to keep track of where to draw the actual graph. If the screen is scrollable, then it will add more complexity.
The other approach, which I think is the easy one, is to have two views (One for the LineChart, and the other for the PopUp). The LineChartView will draw the actual graph, and the PopUp view will cover the entire screen. When the user selects something in the graph, you just need to pass the Graph's values along with the Absolute position on where to draw the popUp to the PopUpView. This way you can draw the popUp anywhere on the screen.