SetVisibility (View.VISIBLE) не всегда работает. Идеи?
Я пытаюсь показать пару скрытых кнопок (используя setVisibility(View.VISIBLE)
, внутри RelativeLayout
), но это не всегда работает. Кнопка показывает OK на вкладке Galaxy Tab 10.1 ", но не на меньшем планшете (не уверен, какая модель), ни на эмуляторе Android 4.0.
Я случайно обнаружил, что для определенного TextView t
следующий код заставляет кнопки становиться видимыми:
t.setText(t.getText());
...
button.setVisibility(View.VISIBLE);
t
находится в том же RelativeLayout
, но не связан с кнопками (их местоположения независимы и не перекрываются).
Изменить. Если какой-либо Android-разработчик хочет отслеживать это...
Мне удалось уменьшить код до следующего макета, который проявляет проблему на эмуляторе 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>
Класс 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());
}
}
Ответы
Ответ 1
SurfaceView является единственным виновником (конечно, это также относится к GLSurfaceView, RSSurfaceView и VideoView, все из которых наследуется от SurfaceView). Он раскрывает множество странных поведений, когда имеет дело с другими представлениями поверх него. Воспроизведение с View.setVisibility() является одной из этих проблем. Очевидно, что SurfaceView не был разработан для использования с другими представлениями (хотя официальный документ говорит, что это должно быть), но как отдельное представление для видео, игр или продуктов OpenGL.
В связи с проблемой видимости, я обнаружил, что с помощью View.GONE вместо View.INVISIBLE разрешите его. Если вы не хотите использовать GONE, попробуйте, например, сфокусировать фокус (и вернуться к тому, на котором раньше была фокус) или изменить другие состояния. Цель состоит в том, чтобы как-то разбудить базовую систему пользовательского интерфейса.
Вкратце: когда что-то странное происходит с вашими взглядами, и у вас есть SurfaceView (или подкласс) где-то, попробуйте заменить его чем-то другим, чтобы вы не теряли часы в поисках того, что вы делаете неправильно, когда вы это делаете право (и без ложных убеждений). Таким образом, вы знаете, что SurfaceView виноват, и вы можете взломать его красивыми комментариями, чтобы мочиться на нем без угрызений совести.
Ответ 2
Для записи: у меня была эта проблема, попробовал кучу случайных вещей (спасибо Alex!), и в моем случае то, что решило это, делало seekBar.requestLayout()
непосредственно после setVisible на самом баре, который отказывался показывать.
Ответ 3
Это мое решение
setAlpha(0)
btnName.setAlpha(0)
Работает для всех видов, таких как = > Кнопки - Изображения - Тексты и...
Ответ 4
В моем случае View.VISIBLE/View.GONE
не работал всегда. Когда я переключил переключатель на View.VISIBLE/View.INVISIBLE
, он начал работать по назначению.
Ответ 5
I (досадно) испытывала схожие трудности с наличием кнопки поверх предварительного просмотра SurfaceView и должна была поместить кнопку в RelativeLayout и сделать RelativeLayout VISIBLE/INVISIBLE. Возможно, стоит того, чтобы кто-то еще имел ту же проблему.
... И мне также пришлось программно вызывать макет, который должен быть перенесен с: buttonLayout.bringToFront() сразу после findViewById.