【问题标题】:force layout to refresh/repaint android?强制布局刷新/重绘android?
【发布时间】:2013-08-30 12:20:48
【问题描述】:

我想改变布局的位置,并在 75 毫秒后将其返回到第一个位置以进行移动,这就是我的代码:

for(int i = 0; i < l1.getChildCount(); i++) {  
    linear = (LinearLayout) findViewById(l1.getChildAt(i).getId());  
    LayoutParams params = new LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);  
    params.bottomMargin = 10;  
    linear.setLayoutParams(params);  
    SystemClock.sleep(75);
}   

问题是应用程序停止了 750 毫秒并且不执行任何操作。我试过invalidate()refreshDrawableState()requestLayout()postInvalidate(),并尝试拨打onResume()onRestart()onPause()

【问题讨论】:

    标签: android layout refresh


    【解决方案1】:

    也许你需要:

    linear.invalidate();
    linear.requestLayout();
    

    进行布局更改后。

    编辑:

    在不同的线程上运行代码:

    new Thread() {
        @Override
        public void run() {
            <your code here>
        }
    }.start();
    

    当您需要从该线程更新 UI 时,请使用:

    activity.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            <code to change UI>
        }
    });
    

    【讨论】:

    • 这段代码放在哪里?如果您在 UI 线程上运行此代码,那么您将停止应用程序并且可能没有任何结果。请更具体地提出您的问题,并且不要在没有用“编辑:”标记的情况下更改问题
    • 感谢您的快速回复,我很抱歉,因为我是新来的,关于代码工作但不显示结果,所有布局在 750 毫秒后同时启动,我不要使用线程thnks。
    • 然后你需要让它在一个单独的线程中运行,并在你需要更新 UI 时使用 runOnUIThread()。
    【解决方案2】:

    经过几个小时的测试,如果您对这些视图进行操作(例如添加子视图、可见性、旋转等),我找到了更新视图的解决方案。

    我们需要使用以下方法强制更新视图。

    linearSliderDots.post {
            // here linearSliderDots is a linear layout &
            // I made add & remove view option on runtime
            linearSliderDots.invalidate()
            linearSliderDots.requestLayout()
        }
    

    【讨论】:

      【解决方案3】:

      您应该尝试使用 ValueAnimator(或对象动画器),以下代码在 kotlin 中,但同样的逻辑将应用于 java:

      val childCount = someView.childCount
          val animators = mutableListOf<ValueAnimator>()
          for (i in 0..childCount) {
              val child = (someView.getChildAt(i))
              val animator = ValueAnimator.ofInt(0, 75)
              animator.addUpdateListener {
                  val curValue = it.animatedValue as Int
                  (child.layoutParams as ViewGroup.MarginLayoutParams).bottomMargin = curValue
                  child.requestLayout()
              }
              animator.duration = 75
              animator.startDelay = 75L * i
              animators.add(animator)
          }
          animators.forEach { animator ->
              animator.start()
          }
      

      基本上你会创建一堆动画,它们的启动延迟与子节点的数量成正比,所以一旦一个动画结束,新的动画就会开始

      【讨论】:

        【解决方案4】:
        ActivityName.this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                <code to change UI>
            }
        });
        

        【讨论】:

        • 我不明白这是如何回答这个问题的。你能解释一下这是如何回答这个问题的吗?
        猜你喜欢
        • 2016-09-21
        • 2014-04-26
        • 1970-01-01
        • 2011-08-24
        • 1970-01-01
        • 2012-02-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多