控制资源的视图可见性

use*_*880 36 android android-imageview android-view android-resources

我有一个包含两个ImageView的布局.我希望其中一个在纵向中可见,另一个在横向中可见.如何使用资源实现它?(我知道如何以编程方式设置它,但我需要使用资源来实现它的特定用途).

我试过类似的东西

在res/layout/may_layout.xml中:

...
<ImageView
      android:id="@+id/image1"
      android:visibility="@integer/visible_in_portrait"   <<-- is this allowed?
      ...
/>
<ImageView
      android:id="@+id/image2"
      android:visibility="@integer/visible_in_landscape"   
      ...
/>
Run Code Online (Sandbox Code Playgroud)

在res/values/integers.xml中:

...
<!-- NOTE: 0 and 8 are VISIBLE and GONE respectively -->
<integer name="visibile_in_portrait">0</integer>
<integer name="visibile_in_landscape">8</integer>
Run Code Online (Sandbox Code Playgroud)

在res/values-land/integers.xml中:

...
<integer name="visibile_in_portrait">8</integer>
<integer name="visibile_in_landscape">0</integer>
Run Code Online (Sandbox Code Playgroud)

但是当我试图给图像充气时,我得到一个运行时错误(索引超出范围).当我删除android:visibility语句时,程序运行但我看到两个图像.

问:将资源用作android:visibility属性的值的方法是什么?

(如果你想知道为什么以编程方式设置它将无法帮助我,它与使用文件uri位图的app小部件的自动landspace/portrait切换有关).

Flá*_*ria 51

这是一个已被接受的旧问题,但以下解决方案可能会帮助其他人:

如果您在Android源代码中检查res/values/attrs.xml,您将看到visibility属性的定义,如下所示:

 <!-- Controls the initial visibility of the view.  -->
    <attr name="visibility">
        <!-- Visible on screen; the default value. -->
        <enum name="visible" value="0" />
        <!-- Not displayed, but taken into account during layout (space is left for it). -->
        <enum name="invisible" value="1" />
        <!-- Completely hidden, as if the view had not been added. -->
        <enum name="gone" value="2" />
    </attr>
Run Code Online (Sandbox Code Playgroud)

此属性需要分别转换为(0,1,2)的字符串值(可见,不可见,消失).因此,您可以声明包含这些值的整数资源,如下所示:

值/ integers.xml

<integer name="visible_in_portrait">2</integer> <!-- This is GONE -->
Run Code Online (Sandbox Code Playgroud)

值-脊/ integers.xml

<integer name="visible_in_landscape">0</integer> <!-- This is VISIBLE -->
Run Code Online (Sandbox Code Playgroud)

但是,如果你想让它更好,以便每次都停止猜测这些数字常量,你可以这样做:

值/ integers.xml

<!-- These are alias for the constants we'll reference below -->
<integer name="view_visible">0</integer> <!-- This is VISIBLE -->
<integer name="view_invisible">1</integer> <!-- This is INVISIBLE -->
<integer name="view_gone">2</integer> <!-- This is GONE -->

<integer name="visible_in_portrait">@integer/view_gone</integer> <!-- We're referencing the visibility alias we declared above -->
Run Code Online (Sandbox Code Playgroud)

值-脊/ integers.xml

<integer name="visible_in_landscape">@integer/view_visible</integer>
Run Code Online (Sandbox Code Playgroud)

您可以使用此方法或Keyhan建议的方法.选择最适合你的那个.

  • 它也可以将它们声明为"<integer>"而不是"<string>" (5认同)
  • 嗯,这不是很好的工作方式.如果检查`View`类代码,则使用这些值(0,1和2)来访问该成员的位置:`private static final int [] VISIBILITY_FLAGS = {VISIBLE,INVISIBLE,GONE};`.这就是为什么你不能使用0,4和8,因为0,1和2代表VISIBLE,INVISIBLE和GONE索引. (3认同)

Key*_*ari 26

当您使用此技巧时,可以将可见性行添加到样式中,并将该文件的两个实例放在-land和normal模式下.

我的意思是在文件styles.xml夹中values放入一个带名字的样式s1,然后放入android:visibility=visible,并styles.xml在文件夹中values-land放一个带名字的样式s1,然后放入android:visibility=gone.

另外,在文件styles.xml夹中values放入带有名称的样式s2,然后放入android:visibility=gone,并styles.xml在文件夹中values-land放入带有名称的样式s2,然后放入android:visibility=visible.

然后,设置s1为第一个imageview和s2第二个.

亲爱的凯文所给出的解决方案也是正确的,但是当你有一个复杂的布局可能会在一段时间内发生变化时,拥有一个布局文件会更好,并且不需要更改.