在多个 parent ViewGroup 上绘制视图边界之外
Drawing outside of the view bounds, over multiple parent ViewGroups
我很欣赏标题写得不是很好,但是有点难以简洁地解释我的问题...
我正在创建一个 Android 应用程序,我有一个自定义图表视图,它有一个小弹出窗口,应该能够超出图表视图本身的范围,并将根据位置自行定位你select在折线图上。
当我在层次结构中有超过 1 个 parent 视图组时,我无法使用它。这是我的布局 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>
如果我删除 CardView,那么只有 ConstraintLayout 作为 parent,它就可以工作。如果我使 CardView 在 Y 方向变大,它允许足够 space 在额外的卡片 space 上绘制弹出窗口。但是像这样,不行。
这有点像它只允许您在 parent 上绘制一次层次结构,但不能再次在大 parent 视图上绘制。
我如何让它在任何和所有 parent 视图的顶部绘制,使其像一个真正的“弹出窗口”?
希望有道理
简单回答:您不能在视图边界之外绘制。
<RelativeLayout>
<RelativeLayout
android:width="400dp"
android:height="400dp">
<LineChartView
android:width="100dp"
android:height="100dp"/>
<RelativeLayout>
</RelativeLayout>
在上面的例子中,如果你检查LineChartView
的onDraw(canvas)
中的Canvas
大小,你会发现高度和宽度都是100dp。这就是您的视图的大小。所以你只能在 space 内绘制。 View 的父级实际上没有任何影响,除非您将 View 的 width/height 设置为动态值,如 MatchParent 或 WrapContent。如果您在视图上执行 MatchParent,则 Canvas 的 width/height 变为 400dp。
本质上,Canvas 的大小决定了哪些 space 可用于绘制以及哪些在屏幕上可见。要解决您的用例,您可以让 LineChartView
填满整个屏幕。但是使用这种方法,您将不得不跟踪绘制实际图形的位置。如果屏幕是可滚动的,那么它会增加更多的复杂性。
另一种方法,我认为是简单的方法,是有两个视图(一个用于 LineChart,另一个用于 PopUp)。 LineChartView 将绘制实际图形,而 PopUp 视图将覆盖整个屏幕。当用户在图表中选择某些内容时,您只需将图表的值以及绘制弹出窗口的绝对位置传递给 PopUpView。这样你就可以在屏幕的任意位置绘制popUp。
我很欣赏标题写得不是很好,但是有点难以简洁地解释我的问题...
我正在创建一个 Android 应用程序,我有一个自定义图表视图,它有一个小弹出窗口,应该能够超出图表视图本身的范围,并将根据位置自行定位你select在折线图上。
当我在层次结构中有超过 1 个 parent 视图组时,我无法使用它。这是我的布局 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>
如果我删除 CardView,那么只有 ConstraintLayout 作为 parent,它就可以工作。如果我使 CardView 在 Y 方向变大,它允许足够 space 在额外的卡片 space 上绘制弹出窗口。但是像这样,不行。
这有点像它只允许您在 parent 上绘制一次层次结构,但不能再次在大 parent 视图上绘制。
我如何让它在任何和所有 parent 视图的顶部绘制,使其像一个真正的“弹出窗口”?
希望有道理
简单回答:您不能在视图边界之外绘制。
<RelativeLayout>
<RelativeLayout
android:width="400dp"
android:height="400dp">
<LineChartView
android:width="100dp"
android:height="100dp"/>
<RelativeLayout>
</RelativeLayout>
在上面的例子中,如果你检查LineChartView
的onDraw(canvas)
中的Canvas
大小,你会发现高度和宽度都是100dp。这就是您的视图的大小。所以你只能在 space 内绘制。 View 的父级实际上没有任何影响,除非您将 View 的 width/height 设置为动态值,如 MatchParent 或 WrapContent。如果您在视图上执行 MatchParent,则 Canvas 的 width/height 变为 400dp。
本质上,Canvas 的大小决定了哪些 space 可用于绘制以及哪些在屏幕上可见。要解决您的用例,您可以让 LineChartView
填满整个屏幕。但是使用这种方法,您将不得不跟踪绘制实际图形的位置。如果屏幕是可滚动的,那么它会增加更多的复杂性。
另一种方法,我认为是简单的方法,是有两个视图(一个用于 LineChart,另一个用于 PopUp)。 LineChartView 将绘制实际图形,而 PopUp 视图将覆盖整个屏幕。当用户在图表中选择某些内容时,您只需将图表的值以及绘制弹出窗口的绝对位置传递给 PopUpView。这样你就可以在屏幕的任意位置绘制popUp。