Android setVisibility(View.VISIBLE) 并不总是有效。想法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11236336/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
setVisibility(View.VISIBLE) doesn't always work. Ideas?
提问by Qwertie
I am trying to show a pair of hidden buttons (using setVisibility(View.VISIBLE)
, within a RelativeLayout
), but it doesn't always work. The button shows OK on a Galaxy Tab 10.1" but not in a smaller tablet (not sure which model), nor on an Android 4.0 emulator.
我正在尝试显示一对隐藏按钮(使用setVisibility(View.VISIBLE)
, 在 a 中RelativeLayout
),但它并不总是有效。该按钮在 Galaxy Tab 10.1" 上显示正常,但在较小的平板电脑(不确定是哪种型号)上显示,也没有在 Android 4.0 模拟器上显示。
I randomly discovered that, for a certain TextView t
, the following code causes the buttons to become visible:
我随机发现,对于某些情况TextView t
,以下代码会导致按钮变为可见:
t.setText(t.getText());
...
button.setVisibility(View.VISIBLE);
t
is located in the same RelativeLayout
but is not related to the buttons (their locations are independent and non-overlapping).
t
位于相同RelativeLayout
但与按钮无关(它们的位置是独立且不重叠的)。
Edit: In case some Android dev wants to track this down...
编辑:如果一些 Android 开发人员想要追踪这个......
I was able to reduce the code to the following layout that exhibits the problem on an Android 4.0.3 emulator but not a Galaxy Tab. I found that I need a SurfaceView
or the problem does not occur (for example, change it to TextView
and the problem disappears).
我能够将代码简化为以下布局,该布局在 Android 4.0.3 模拟器上而不是在 Galaxy Tab 上表现出问题。我发现我需要一个SurfaceView
或问题不发生(例如,将其更改TextView
为问题消失)。
<?xml version="1.0" encoding="utf-8"?>
<!-- layout/test.xml -->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/relativeLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<SurfaceView
android:id="@+id/mapCtrl"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="@+id/bottomPanel"
android:text="Placeholder"
android:layout_marginTop="18dip" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="@string/map_mode_title" />
<!--=================================================-->
<!-- Bottom bar: current road name and current speed -->
<LinearLayout
android:id="@+id/bottomPanel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#f228"
android:orientation="horizontal"
android:textColor="#ffff" >
<Button
android:id="@+id/btnNavMode"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginRight="3dip"
android:textColor="#fff"
android:text="Switch to\nNav Mode" />
<RelativeLayout
android:id="@+id/currentStreetPanel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="onClick"
android:clickable="true"
android:orientation="vertical" >
<TextView
android:id="@+id/currentStreetHdg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Current street"
android:textColor="#fff"
android:textSize="10dip" />
<TextView
android:id="@+id/currentStreet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/currentStreetHdg"
android:layout_marginTop="-8dip"
android:singleLine="true"
android:text="Current street"
android:textColor="#fff"
android:textSize="30dip" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/RelativeLayout2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#ff606060"
android:orientation="vertical" >
<TextView
android:id="@+id/yourSpeedHdg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="3dip"
android:text="Your speed"
android:textColor="#fff"
android:textSize="10dip" />
<TextView
android:id="@+id/speed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/yourSpeedHdg"
android:layout_marginLeft="3dip"
android:layout_marginTop="-8dip"
android:text="0"
android:textColor="#fff"
android:textSize="30dip" />
<TextView
android:id="@+id/speedUnit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/speed"
android:layout_marginLeft="5dip"
android:layout_toRightOf="@+id/speed"
android:text="kph"
android:textColor="#fff"
android:textSize="18dip" />
</RelativeLayout>
</LinearLayout>
<!--================-->
<!-- On-map buttons -->
<Button
android:id="@+id/btnClearRoute"
android:background="#F00"
android:textColor="#fff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Clear\nroute"/>
<ZoomControls
android:id="@+id/zoomControls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/mapCtrl"
android:layout_centerHorizontal="true"
android:layout_marginBottom="-25dip"
android:orientation="horizontal" />
<Button
android:id="@+id/btnFindRoute"
android:layout_width="100dip"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/mapCtrl"
android:layout_alignParentRight="true"
android:layout_marginRight="2dip"
android:layout_marginBottom="65dip"
android:text="Route to selected location"
android:textSize="17dip"/>
<Button
android:id="@+id/btnUnselect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/btnFindRoute"
android:layout_alignTop="@+id/btnFindRoute"
android:layout_alignParentLeft="true"
android:layout_marginLeft="2dip"
android:text="Unselect" />
<LinearLayout
android:id="@+id/showMePanel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/btnFindRoute"
android:layout_alignRight="@+id/btnFindRoute"
android:layout_alignLeft="@+id/btnFindRoute"
android:padding="4dip"
android:background="#bbbb"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show me..."
android:textColor="#fff"/>
<Button
android:id="@+id/btnShowVehicle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="My car"/>
<Button
android:id="@+id/btnShowRoute"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="The route"/>
<Button
android:id="@+id/btnShowDestination"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Destination"/>
<Button
android:id="@+id/btnShowMap"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="The map"/>
</LinearLayout>
</RelativeLayout>
The Activity class simply toggles the visibility of the two buttons when any of the buttons are clicked. Again, on some devices it works, on others it does not.
Activity 类只是在单击任何按钮时切换这两个按钮的可见性。同样,在某些设备上它有效,而在其他设备上则无效。
package mentor.simplegps;
import android.app.*;
import android.os.Bundle;
import android.view.*;
import android.widget.*;
public class TestActivity extends Activity implements View.OnClickListener
{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.test);
boilerplate();
setVisibilities();
}
Button _btnShowMap, _btnShowVehicle, _btnShowRoute, _btnShowDestination;
Button _btnUnselect, _btnFindRoute, _btnNavMode;
TextView _title;
void boilerplate()
{
_btnUnselect = attachBtn(R.id.btnUnselect);
_btnShowMap = attachBtn(R.id.btnShowMap);
_btnShowVehicle = attachBtn(R.id.btnShowVehicle);
_btnShowRoute = attachBtn(R.id.btnShowRoute);
_btnShowDestination = attachBtn(R.id.btnShowDestination);
_btnFindRoute = attachBtn(R.id.btnFindRoute);
_btnNavMode = attachBtn(R.id.btnNavMode);
_title = (TextView)findViewById(R.id.title);
}
private Button attachBtn(int btnId) {
Button b = (Button)findViewById(btnId);
b.setOnClickListener(this);
return b;
}
boolean haveSel;
public void onClick(View v)
{
haveSel = !haveSel;
setVisibilities();
}
void setVisibilities()
{
_btnFindRoute.setVisibility(haveSel ? View.VISIBLE : View.INVISIBLE);
_btnUnselect.setVisibility (haveSel ? View.VISIBLE : View.INVISIBLE);
// Fixes the problem
//_title.setText(_title.getText());
}
}
回答by Alex
SurfaceView is the sole culprit (of course, this also applies to GLSurfaceView, RSSurfaceView and VideoView, all of which inherits from SurfaceView). It exposes lots of weird behaviours when dealing with other views on top of it. Playing with View.setVisibility() is one of those issues. Clearly, SurfaceView has not been designed to be used with other views (even though the official doc says it ought to be) but as a standalone view for videos, games or OpenGL stuffs.
SurfaceView 是唯一的罪魁祸首(当然,这也适用于 GLSurfaceView、RSSurfaceView 和 VideoView,它们都继承自 SurfaceView)。在处理其上的其他视图时,它会暴露出许多奇怪的行为。使用 View.setVisibility() 是这些问题之一。显然,SurfaceView 并没有被设计为与其他视图一起使用(即使官方文档说它应该是),而是作为视频、游戏或 OpenGL 内容的独立视图。
For the visibility issue, I've found that using View.GONE instead of View.INVISIBLE resolve it. If you don't want to use GONE, try changing the focus for example (and back to the one that had focus before), or changing other states. The goal is to wake up the underlying UI system somehow.
对于可见性问题,我发现使用 View.GONE 而不是 View.INVISIBLE 可以解决它。如果您不想使用 GONE,请尝试更改焦点(并返回到之前的焦点),或更改其他状态。目标是以某种方式唤醒底层 UI 系统。
In short: when something weird happens with your views and you have a SurfaceView (or subclass) somewhere, try replacing it with something else so you don't lose hours searching what you're doing wrong when you're doing it right (and no false beliefs). This way, you know SurfaceView is to blame and you can hack around it with beautiful comments to piss on it without qualms.
简而言之:当你的视图发生奇怪的事情并且你在某处有一个 SurfaceView(或子类)时,尝试用其他东西替换它,这样你就不会浪费时间去搜索你做错了什么,当你做对了(和没有错误的信念)。通过这种方式,您知道 SurfaceView 是罪魁祸首,您可以用漂亮的评论绕过它,毫无顾虑地对它撒尿。
回答by Chani
For the record: I had this problem, tried a bunch of random stuff (thanks Alex!), and in my case what solved it was doing seekBar.requestLayout()
directly after the setVisible on the very seekbar that was refusing to show.
记录:我遇到了这个问题,尝试了一堆随机的东西(感谢亚历克斯!),在我的情况下,解决它的方法是在seekBar.requestLayout()
拒绝显示的搜索栏上的 setVisible 之后直接执行。
回答by Mahdi Hossaini
This is my Solution
这是我的解决方案
setAlpha(0)
btnName.setAlpha(0)
Is working for all views like => Buttons - Images - Texts and ...
适用于所有视图,例如 => 按钮 - 图像 - 文本和 ...
回答by Rafael
In my case View.VISIBLE/View.GONE
was not working always. When I switched my toggle to View.VISIBLE/View.INVISIBLE
it started to work as intended.
在我的情况下View.VISIBLE/View.GONE
并不总是有效。当我将切换开关切换到View.VISIBLE/View.INVISIBLE
它时,它开始按预期工作。
回答by Blaze Gawlik
I (annoyingly) had similar difficulty with having a button on top of a SurfaceView preview and had to put the Button in a RelativeLayout and make the RelativeLayout VISIBLE/INVISIBLE. Might be worth a shot for anyone else having the same issue.
我(恼人地)在 SurfaceView 预览顶部有一个按钮时遇到了类似的困难,不得不将 Button 放在 RelativeLayout 中并使 RelativeLayout 可见/不可见。对于有同样问题的其他人来说,可能值得一试。
...And I also had to programatically call the layout to be brought to from: buttonLayout.bringToFront() right after findViewById.
...而且我还必须在 findViewById 之后以编程方式调用要从以下位置获取的布局:buttonLayout.bringToFront()。