更改布局时,CoordinatorLayout自定义行为onDependentViewChanged被破坏

时间:2016-11-25 14:57:24

标签: android android-layout android-fragments android-coordinatorlayout

我使用Custom CoordinatorLayout Behavior来跟踪CoordinatorLayout中的滑动功能,将两个小部件一起滑动并且它可以工作(类似于Custom BottomSheetBehavior +另一个跟随底部位置的行为),但在某些情况下它会被破坏。

布局结构有点复杂,但它是这样的:

CoordinatorLayout (root tag of activity layout)
 - Fragment (DetailFragment)
   - CoordinatorLayout (root tag of DetailFragment)
     - Fragment (MapFragment - with custom app:layout_behavior)
     - CoordinatorLayout (also with another custom app:layout_behavior)
       - NestedScrollView
         - LinearLayout
           - LinearLayout
             - Some content

MapFragment元素上安装的自定义行为依赖于以下元素(CoordinatorLayout)上的layoutDependsOn()方法。此后续元素具有自己的自定义行为,可以使用滑动手势将其向上滑动。在这种情况下,MapFragment的自定义行为会在其依赖项的每次移动时接收事件onDependentViewChanged。

但是,如果我在调用一些内容的部分进行更改,例如我调用setVisibility或者我将ListView放在其上并调用setAdapter(此方法通常调用requestLayout方法 - 这与布局更改有关,如setVisibility它似乎停止工作,这意味着即使相关视图位置已更改,MapFragment的自定义行为也会停止接收onDependentViewChanged。

这个问题可能还有一些隐藏的条件让它发生。所以我需要找到隐藏的原因,或者解决方法如何让它工作。

因为,如果我在活动中使用Detail片段,则会出现此问题,但在另一个活动中,它似乎有效。

我也忘了说,它还表明另一个额外的问题,即setVisibility方法不起作用 - 元素保持隐藏+ CL的行为被破坏(在有问题的活动中。顺便说一下 - 当我有listview时在我的布局中,并在其上调用了setAdapter,它也不起作用 - 正如我所说的,它显然与setVisibility方法类似。)

是的,我试图通过UI线程显式调用setVisibility,如

  getActivity().runOnUiThread(new Runnable(){
    @Override
    public void run() {
      xxx.setVisibility(View.VISIBLE);  
  }});

但它没有帮助。感谢

附加说明:

  • 在有问题的Activity中,至少调用一次onDevivment行为方法onDependentViewChanged(当显示活动时 - 应指示依赖关系应该正确链接),我认为它找到正确的CoordinatorLayout作为其依赖关系。但问题是如果我改变其依赖性的位置,这个事件就不再被触发了。

  • 在我调用setVisibility方法的片段代码中,我也尝试在它之后调用getView()。requestLayout()但它没有帮助。

  • 另请注意,我尝试调用setVisibility的元素是在屏幕外的那一刻(因为MapFragment之后的CoordinatorLayout上的自定义行为类似于BottomSheetBehavior),所以如果它不是一些问题(在工作活动中,它显示在屏幕上 - BottomSheet显示为展开,未隐藏或折叠,如有问题的活动中所示)

修改

它必须是半死或懒惰的UI事件消息系统左右,因为我发现如果我改变活动布局中其他元素的可见性,瞧 - 地图自定义行为再次开始工作! - 虽然我试图将setVisibility设置为visible的元素仍然被隐藏..

所以这是片段中的代码:

getView().findViewById(R.id.info_beer_bdark).setVisibility(View.VISIBLE);

如果我将其更改为:

getView().findViewById(R.id.info_beer_bdark).setVisibility(View.VISIBLE);
getActivity().findViewById(R.id.tabs).setVisibility(View.GONE);

MapFragment的行为再次起作用 - 尽管如我所说,我试图使可见的元素仍然隐藏 - 也许它在布局级别上也需要一些“刷新注入”。 (选项卡与DetailFragment元素位于相同的布局级别)

1 个答案:

答案 0 :(得分:0)

问题的原因可能是因为我在其自定义行为中使用下面显示的代码动画了CoordinatorLayout(在MapFragment之后),并且在动画期间更改了其子项的可见性。

 ViewCompat.postOnAnimation(child, new SettleRunnable(child, state));

伪代码:

 startCoordinatorUIAnimation(); // it takes like 300ms
 changeVisibilityOfCoordinatorChildren(); // doesn't work while animating + breaks Coordinator Behavior

我仍然不知道如何实现这一点 - 在动画父母时改变儿童的可见度。我尝试了runOnUIThread,也使用了runOnUIThread的AsyncTask但是没有用。