3

谁能解释一下何时调用View.drawableStateChanged?我想将它与ViewGroup.setAddStatesFromChildren结合使用以实现完整的“光学”聚焦,这ViewGroup意味着例如当其中一个获得焦点时更改背景颜色。EditTextViewGroup

当我实现View.drawableStateChanged它经常被调用时,我怎么知道当前调用是我关心的那个?设置焦点侦听器在子视图上的优势是什么?

4

3 回答 3

5

您可以在此处了解更多信息。

View.drawableStateChanged()每当视图的状态发生变化从而影响正在显示的可绘制对象的状态时都会调用。

如果您像这样创建可绘制对象:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true"
          android:color="#ffff0000"/> 
    <item android:state_focused="true"
          android:color="#ff0000ff"/> 
    <item android:state_enabled="true"
          android:color="#ff00ffff"/> 
    <item android:color="#ff000000"/> 
</selector>

这个drawable主要有不同的状态(比如state_pressed,,,state_focusedstate_enabled。如果您已将 drawable 设置为特定视图并且该视图是可点击的,那么当您单击该视图时,此状态通常会发生变化。

您可以使用它setOnFocusChangeListener来检查焦点变化和setOnTouchListener触摸事件。此外,您可以检查以启用/禁用该onClick()视图的状态事件。

更新:此方法已弃用,请点击此链接了解更多信息。

于 2020-05-29T07:46:25.120 回答
0

通过阅读文档,其中指出:

This function is called whenever the state of the view changes in 
such a way that it impacts the state of drawables being shown.

似乎每当需要重绘组件时框架都会调用此函数,并且您可以覆盖它以(例如)执行重绘组件时需要执行的特定于应用程序的逻辑,例如手动在组件的顶部,或更改字体或做一些使用股票属性不可能的事情。

这个问题有一个你可以如何实现它的例子。

于 2020-05-31T10:07:10.887 回答
0

为简单起见,您希望您的整体Viewgroup集中在其中一个孩子实际上集中注意力时,您只需要ViewGroup.setAddStatesFromChildren 创建一个drawable文件,我在我的代码中将其称为 view_focus

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="true" android:state_focused="true">
        <shape android:shape="rectangle">
            <solid android:color="@color/white"/>
            <corners android:radius="19dp"/>
            <stroke android:color="@color/green" android:width="2dp"/>
        </shape>
    </item>

    <item android:state_enabled="true" android:state_focused="false">
        <shape android:shape="rectangle">
            <solid android:color="@color/white"/>
            <corners android:radius="19dp"/>
            <stroke android:color="@color/black" android:width="2dp"/>
        </shape>
    </item>

</selector>

现在在您的活动布局中,您必须将上述可绘制对象作为背景传递给您的 Viewgroup 及其子项,如下所示:

    <RelativeLayout
        android:background="@drawable/view_focus"
        android:layout_centerInParent="true"
        android:id="@+id/parentlayout"
        android:layout_width="300dp"
        android:layout_height="250dp">
        <EditText
            android:padding="5dp"
            android:textSize="20sp"
            android:layout_centerInParent="true"
            android:background="@drawable/view_focus"
            android:id="@+id/edit"
            android:layout_width="200dp"
            android:layout_height="wrap_content"/>
        <EditText
            android:padding="5dp"
            android:textSize="20sp"
            android:layout_centerInParent="true"
            android:background="@drawable/view_focus"
            android:layout_below="@+id/edit"
            android:layout_marginTop="20dp"
            android:layout_width="200dp"
            android:layout_height="wrap_content"/>

    </RelativeLayout>

在这种情况下,RelativeLayoutparentlayout 是Viewgroup并且它的孩子是两个EditText如果你执行这个代码只有孩子们会Focus在点击后获得,如果你想要你的整个 ViewGroup 获得焦点你需要在你的活动类文件中添加这一行:

relativeLayout = findViewById(R.id.parentlayout);
relativeLayout.setAddStatesFromChildren(true);

这是使用上述行后的结果。

后

这在使用之前ViewGroup.setAddStatesFromChildren 前

于 2020-05-30T13:33:46.300 回答