【问题标题】:Android: why setVisibility(View.GONE); or setVisibility(View.INVISIBLE); do not workAndroid:为什么要设置可见性(View.GONE);或 setVisibility(View.INVISIBLE);不工作
【发布时间】:2011-11-12 23:19:33
【问题描述】:

我希望我的DatePicker 和按钮在开始时不可见。当我按下我的魔法按钮时,我想 setVisibility(View.Visible);

这里的问题是当我setVisibility(View.GONE)setVisibility(View.INVISIBLE) 没有任何变化并且组件仍然可见时。

final DatePicker dp2 = (DatePicker) findViewById(R.id.datePick2);
final Button btn2 = (Button) findViewById(R.id.btnDate2);

dp2.setVisibility(View.GONE);
dp2.setVisibility(View.INVISIBLE);
btn2.setVisibility(View.GONE);
btn2.setVisibility(View.INVISIBLE);

btn2.setOnClickListener(new View.OnClickListener() {
    public void onClick(View arg0) {
        TextView txt2 = (TextView) findViewById(R.id.txt2);
        txt2.setText("You selected " + dp2.getDayOfMonth()
            + "/" + (dp2.getMonth() + 1) + "/" + dp2.getYear());
    }
});

【问题讨论】:

    标签: java android android-layout android-view android-datepicker


    【解决方案1】:

    我发现很多事情都错了。对于初学者,您没有定义魔术按钮,也没有事件处理程序。

    你也不应该使用:

    dp2.setVisibility(View.GONE);
    dp2.setVisibility(View.INVISIBLE); 
    

    只使用两者之一。来自Android documentation

    View.GONE 这个视图是不可见的,它不占用任何空间 布局目的。

    View.INVISIBLE 这个视图是不可见的,但它仍然 占用空间用于布局。

    在您的示例中,您将使用 View.INVISIBLE 覆盖 View.GONE 分配。


    尝试替换:

    final DatePicker dp2 = new DatePicker(this)
    

    与:

    DatePicker dp2 = (DatePicker) findViewById(R.id.datePick2);  
    

    对于其他小部件也是如此:

        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            LinearLayout ll = new LinearLayout(this);
            ll.setOrientation(LinearLayout.VERTICAL);
    
            final DatePicker dp2 = new DatePicker(this);
            final Button btn2 = new Button(this);
            final Button magicButton = new Button(this);
            final TextView txt2 = new TextView(TestActivity.this);
    
            dp2.setVisibility(View.GONE);
            btn2.setVisibility(View.GONE);
            btn2.setText("set Date");
    
            btn2.setOnClickListener(new View.OnClickListener() {
                public void onClick(View arg0) {
                    txt2.setText("You selected "
                        + dp2.getDayOfMonth() + "/" + (dp2.getMonth() + 1) 
                        + "/" + dp2.getYear());
                }
            });
    
            magicButton.setText("Magic Button");
            magicButton.setOnClickListener(new View.OnClickListener()    
                public void onClick(View arg0) {
                    dp2.setVisibility(View.VISIBLE);
                    btn2.setVisibility(View.VISIBLE);
                }
            });
    
        ll.addView(dp2);
        ll.addView(btn2);
        ll.addView(magicButton);
        ll.addView(txt2);
    
        setContentView(ll);
    }
    

    【讨论】:

      【解决方案2】:

      今天我有一个场景,我正在执行以下操作:

      myViewGroup.setVisibility(View.GONE);
      

      就在下一帧,我正在其他地方执行if 检查该视图的可见性状态。你猜怎么了?以下条件通过:

      if(myViewGroup.getVisibility() == View.VISIBLE) {
          // this `if` was fulfilled magically
      }
      

      放置断点可以看到,可见性变为GONE,但在下一帧它神奇地变为VISIBLE。我试图理解这到底是怎么发生的。

      原来有一个动画应用于这个视图,这在内部导致视图将其可见性更改为VISIBLE,直到完成动画:

      public void someFunction() {
          ...
          TransitionManager.beginDelayedTransition(myViewGroup);
          ...
      
          myViewGroup.setVisibility(View.GONE);
      }
      

      如果您进行调试,您会看到 myViewGroup 确实将其可见性更改为 GONE,但在下一帧它会再次变为可见以运行动画。

      因此,如果您遇到这种情况,请确保您没有在为视图设置动画的过程中执行if 签入。

      您可以通过View.clearAnimation() 删除视图上的所有动画。

      【讨论】:

      • 这就是我的答案(View.clearAnimation())。当您知道您在其上设置了动画时,请始终在要设置为 GONE 的视图上调用 View.clearAnimation()。
      • 这确实有效,调试没有发现任何问题,因为可见性确实按预期设置!
      • 谢谢!我花了很多时间弄清楚为什么可见性不起作用,而您的解决方案对我有用!
      • 它对我不起作用,因为我使用 androidx.constraintlayout.motion.widget.MotionLayout 作为视图的容器。
      【解决方案3】:

      您可以将其视为 CSS 样式的可见性和显示。

      <div style="visibility:visible; display:block">
          This is View.VISIBLE : Content is displayed normally.
      </div>
      
      <div style="visibility:hidden; display:block">
          This is View.INVISIBLE : Content is not displayed, but div still takes up place, but empty.
      </div>
      
      <div style="display:none">
          This is View.GONE : Container div is not shown, you can say the content is not displayed.
      </div>
      

      【讨论】:

        【解决方案4】:

        首先看你的代码:

        dp2.setVisibility(View.GONE);
        dp2.setVisibility(View.INVISIBLE);
        btn2.setVisibility(View.GONE);
        btn2.setVisibility(View.INVISIBLE);
        

        在这里,您将两个可见性设置为同一字段,这就是问题所在。 我给了一个样品sample demo

        【讨论】:

        • ArrayAdapter adapter7 = new ArrayAdapter(Application.getContext(), android.R.layout.simple_spinner_item, options()); Spinner spinnerEnd = (Spinner) findViewById(R.id.spinnerEnd); adapter7.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinnerEnd.setAdapter(adapter7); spinnerEnd.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { public void onItemSelected(AdapterView> adapterView, View view, int i, long l) { dp2.setVisibility(View.VISIBLE); btn2.setVisibility(View.VISIBLE);
        • 问题出在此处。因为进入 onItemSelect
        • 试试这个按钮 btn1,btn2;微调器旋转; btn1=(按钮)findViewById(R.id.button1); spin=(Spinner)findViewById(R.id.spinner1);字符串[] sample11={"样品","HI"}; spin=(Spinner)findViewById(R.id.spinner1); ArrayAdapter 适配器 = new ArrayAdapter (this, android.R.layout.simple_spinner_item,sample11); spin.setAdapter(适配器); btn1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO 自动生成的方法 stub spin.setVisibility(View.GONE); } });
        • 是的,所以我想检查一下 IF CONDITION 但我做不到。
        【解决方案5】:

        就我而言,我发现在将可见性设置为GONE 之前清除视图上的动画即可。

        dp2.clearAnimation();
        dp2.setVisibility(View.GONE);
        

        我有一个类似的问题,我在两个视图之间切换,其中一个必须始终以 GONE 开头 - 但是当我再次显示视图时,即使调用了 setVisibility(GONE),它也会显示在第一个视图之上。在将视图设置为 GONE 之前清除动画是可行的。

        【讨论】:

          【解决方案6】:

          View.GONE 这个视图是不可见的,它不占用任何空间用于布局。

          View.INVISIBLE 这个视图是不可见的,但它仍然占用空间用于布局。

          dp2.setVisibility(View.GONE);
          dp2.setVisibility(View.INVISIBLE);
          btn2.setVisibility(View.GONE);
          btn2.setVisibility(View.INVISIBLE);
          

          【讨论】:

            【解决方案7】:

            这适用于尝试了所有答案但仍然失败的人。扩展pierre's 答案。如果您使用动画,将可见性设置为 GONEINVISIBLEinvalidate() 将永远不会起作用。试试下面的解决方案。 `

            btn2.getAnimation().setAnimationListener(new Animation.AnimationListener() {
                 @Override
                 public void onAnimationStart(Animation animation) {
                 }
                 @Override
                 public void onAnimationEnd(Animation animation) {
                     btn2.setVisibility(View.GONE);
                     btn2.clearAnimation();
                 }
                 @Override
                 public void onAnimationRepeat(Animation animation) {
                 }
            });
            

            `

            【讨论】:

              【解决方案8】:

              View.GONE 使视图不可见,而视图不占用布局中的空间。 View.INVISIBLE 使视图不可见仍然占用空间。

              您首先在同一个视图上使用 GONE 然后 INVISIBLE。由于代码是按顺序执行的,首先视图变为 GONE 然后它被 INVISIBLE 类型覆盖,仍然占用空间。

              您应该在按钮上添加按钮侦听器,并在 onClick() 方法内使视图可见。这应该是我在 onCreate() 方法中的逻辑。

              @Override
              protected void onCreate(Bundle savedInstanceState) {
                  super.onCreate(savedInstanceState);
                  setContentView(R.layout.activity_setting);
              
                  final DatePicker dp2 = (DatePicker) findViewById(R.id.datePick2);
                  final Button btn2 = (Button) findViewById(R.id.btnDate2);
                  final Button btn3 = (Button) findViewById(R.id.btnVisibility);
              
                  dp2.setVisibility(View.INVISIBLE);
                  btn2.setVisibility(View.INVISIBLE);
              
                  bt3.setOnClickListener(new View.OnCLickListener(){ 
                  @Override
                  public void onClick(View view)
                  {
                      dp2.setVisibility(View.VISIBLE);
                      bt2.setVisibility(View.VISIBLE);
                  }
                });
              }
              

              我认为这应该很容易。希望这会有所帮助。

              【讨论】:

                【解决方案9】:

                我也面临同样的问题,如果假设特定片段在各个屏幕上膨胀,则 if 语句中设置的可见性模式有可能无法根据我们的需要运行,因为条件可能已被重置它在我们的应用中被充气了很多次。

                就我而言,我必须根据在另一个片段(父片段)中单击的按钮来更改一个片段(子片段)中的可见性模式。因此,我将 buttonClicked 布尔值存储在父片段的变量中,并将其作为参数传递给子片段中的函数。因此,子片段中的可见性模式会根据通过参数接收的布尔值进行更改。但是随着这个子片段在各个屏幕上膨胀,即使我使用 View.GONE 将其隐藏,可见性模式也会不断重置。

                为了避免这种冲突,我在子片段中声明了一个静态布尔变量,每当从父片段接收到该布尔值时,我将其存储在静态变量中,然后根据该静态变量更改可见性模式子片段。

                这解决了我的问题。

                【讨论】:

                  【解决方案10】:

                  我曾经遇到过同样的问题。在更改可见性后调用 invalidate 几乎总是有效,但在某些情况下则无效。我不得不作弊并将背景设置为透明图像并将文本设置为“”。

                  【讨论】:

                    【解决方案11】:

                    因为您将可见性设置为真或假。 试试看 setVisible(0) 可见 true 。 and setVisible(4) 可见错误。

                    【讨论】:

                    • 文本可以不可见,但按钮和日期选择器没有。
                    • 不要使用文字整数,这是个坏习惯,请改用 View.GONE 或 View.VISIBLE...
                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2020-10-31
                    • 1970-01-01
                    • 1970-01-01
                    • 2015-09-10
                    • 1970-01-01
                    • 2012-03-22
                    • 2013-04-17
                    相关资源
                    最近更新 更多