Android fragments view.animate()不';第一次不工作,但以后会工作 总结:
视图以可见性='GONE'开始。当视图设置为可见时,我希望它下面的所有内容都向下移动该视图的高度。第一次不起作用,但之后每次都起作用 说明: 我用的是一个广播组,它有三种传送方式 如果用户单击第三个选项,则会出现第二个收音机组,其中显示更多选项 仅当选择了第一个收音机组的第三个选项时,第二个收音机组才可见。当它变得可见时,我希望它下面的所有东西都向下滑动以腾出空间。我添加了view.animate().translationY()对两个无线组下面的每个视图的调用。当第二个广播组出现时,它可以将所有东西移开,当它消失时,将它们滑回原位。问题是,这种方法只在第二次使用时有效。无线电组第一次出现时,所有视图都保持不变 尝试:Android fragments view.animate()不';第一次不工作,但以后会工作 总结:,android-fragments,visibility,slide,visible,android-constraintlayout,Android Fragments,Visibility,Slide,Visible,Android Constraintlayout,视图以可见性='GONE'开始。当视图设置为可见时,我希望它下面的所有内容都向下移动该视图的高度。第一次不起作用,但之后每次都起作用 说明: 我用的是一个广播组,它有三种传送方式 如果用户单击第三个选项,则会出现第二个收音机组,其中显示更多选项 仅当选择了第一个收音机组的第三个选项时,第二个收音机组才可见。当它变得可见时,我希望它下面的所有东西都向下滑动以腾出空间。我添加了view.animate().translationY()对两个无线组下面的每个视图的调用。当第二个广播组出现时,它可以将所
- SystemClock--我尝试添加SystemClock.sleep(1500)呼叫。这只是给动画增加了一个延迟,但第一次仍然不起作用
- 处理程序——我尝试添加一个处理程序来处理动画视图,同样的问题
- 启动延迟——我已经尝试添加一个启动延迟,正如前面提到的和这里提到的
- 硬编码高度——我已经尝试硬编码向下移动的距离。我想问题可能是,在设置为visible后,通过调用无线电组上的getHeight()来获取移动的高度。如果这就是问题所在,我认为硬编码高度可能会奏效,但同样的问题依然存在
- 垂直链--我尝试将所有视图附加到垂直链中,并在无线组可见时将其添加到链中。当可见性“消失”时,广播组无法包含在链中,将其添加到链中没有任何作用。如果在可见性设置为“可见”后将其添加到约束布局中,应用程序将崩溃
- 这是在一个片段中发生的
- 代码位于onCreateView方法内的switch语句中
- 该片段位于主活动内,主活动具有带选项卡的视图寻呼机
- 如果要在文件中查找代码,请在java/com/example/OrderScreenFragment.java下查找
- 我真的环顾四周,找不到发生这种情况的原因,请不要标记为重复或模糊。如果你需要澄清什么,我很乐意澄清
gone
的无线电组布局首次出现时,无线电组的高度已测量为零,因为gone
小部件没有高度(或者,可能只是因为它已gone
而未测量)。因此,当您参考其高度时,toMove
变为零。现在无线电组已可见,安卓将对其进行测量并进行布局。不幸的是,由于toMove==0
,无线电组没有移动。(使用getHeight()
捕获高度后,会进行测量和布局)
当无线电组再次标记为消失
,然后标记为可见
,则toMove
获取无线电组的高度,因为它是先前测量的,并且存储了这些测量值。有关更多详细信息,请参阅
要解决此问题,需要明确测量无线电组。我已在下面对您的onCreateView()
进行了更改:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the Layout for this fragment
View myView = inflater.inflate(R.layout.fragment_order, container, false);
constraintLayout = (ConstraintLayout) myView.findViewById(R.id.order_screen_layout);
set = new ConstraintSet();
set.clone(constraintLayout);
set.applyTo(constraintLayout);
// Radio Groups
RadioGroup deliveryGroup = (RadioGroup) myView.findViewById(R.id.radioGroup);
stdDeliveryGroup = (RadioGroup) myView.findViewById(R.id.std_delivery_group);
deliveryGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
public void onCheckedChanged(RadioGroup group, int checkedId) {
// Checked ID is the radio button selected
switch (checkedId) {
case R.id.pickup_radio_button:
shipping = 0;
delivery = PICKUP;
deliveryType = "Pick-Up";
updatePrice();
stdDeliveryGroup.setVisibility(View.GONE);
break;
case R.id.free_delivery_radio:
shipping = 0;
delivery = CBD_DELIVERY;
deliveryType = "CBD - Delivery";
updatePrice();
stdDeliveryGroup.setVisibility(View.GONE);
break;
case R.id.standard_delivery_radio:
// ToDo: Impliment delivery charges if delivering outside of CBD
delivery = STD_DELIVERY;
deliveryType = "Standard Delivery";
stdDeliveryGroup.setVisibility(View.VISIBLE);
// SystemClock.sleep(2000);
break;
}
if (stdDeliveryGroup.getVisibility() == View.VISIBLE) {
// Force measurement since view was "gone" at last measurement.
if (stdDeliveryGroup.getMeasuredHeight() == 0) {
// Only force measurement if the view is gone; otherwise, the normal flow
// will work.
ViewGroup.LayoutParams lp = stdDeliveryGroup.getLayoutParams();
int widthSpec = View.MeasureSpec.makeMeasureSpec(lp.width, View.MeasureSpec.EXACTLY);
int heightSpec = View.MeasureSpec.makeMeasureSpec(lp.height, View.MeasureSpec.EXACTLY);
stdDeliveryGroup.measure(widthSpec, heightSpec);
}
toMove = stdDeliveryGroup.getMeasuredHeight();
}
if (stdDeliveryGroup.getVisibility() == View.GONE) {
toMove = 0;
}
shippingNumber.animate().translationY(toMove);
shippingText.animate().translationY(toMove);
orderButton.animate().translationY(toMove);
totalText.animate().translationY(toMove);
totalNumber.animate().translationY(toMove);
}
});
return myView;
}
经过思考,我意识到,如果无线组的大小没有以精确的单位指定,那么前面的解决方案就会有问题。最初将无线电组的可见性设置为
visible
的另一种方法。这将导致Android对无线电组进行测量和布局。然后,我们将使用ConstraintLayout
上的预绘制侦听器中止布局的绘制,并将可见性设置为gone
。将XML中无线电组的可见性更改为visible
,并将以下代码添加到onCreate()
纠正这个问题的另一种方法,也许是最好的方法,就是稍微修改一下布局。约束要向下滑动到
gone
无线电组底部的小部件的顶部。现在可以使用ConstraintSet
和TransitionManager.beginDelayedTransition()
制作动画。有关介绍,请参见本教程。如果需要对页边距进行一些调整,请查看ConstraintLayout
文档。解决方案:
我最终通过使用visibility=(visible<=>invisible)解决了这个问题
说明:
最初,可见性从(变为<=>可见)
通过在活动开始时将其设置为“不可见”,我可以测量组的高度,但它不会以任何其他方式影响布局。感谢@Cheticamp为我指明了正确的方向。它确实没有首先测量视图的高度,即使对getHeight()的调用是在视图设置为visible之后进行的
前两个答案对我都不起作用,它们仍然做着同样的事情。对于最后的约束布局建议,我无法将视图的约束附加到设置为“gone”的视图底部
我不知道“看不见”的观点是否是理想的解决方案,但它是有愿望的
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the Layout for this fragment
View myView = inflater.inflate(R.layout.fragment_order, container, false);
constraintLayout = (ConstraintLayout) myView.findViewById(R.id.order_screen_layout);
set = new ConstraintSet();
set.clone(constraintLayout);
set.applyTo(constraintLayout);
// Radio Groups
RadioGroup deliveryGroup = (RadioGroup) myView.findViewById(R.id.radioGroup);
stdDeliveryGroup = (RadioGroup) myView.findViewById(R.id.std_delivery_group);
deliveryGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
public void onCheckedChanged(RadioGroup group, int checkedId) {
// Checked ID is the radio button selected
switch (checkedId) {
case R.id.pickup_radio_button:
shipping = 0;
delivery = PICKUP;
deliveryType = "Pick-Up";
updatePrice();
stdDeliveryGroup.setVisibility(View.GONE);
break;
case R.id.free_delivery_radio:
shipping = 0;
delivery = CBD_DELIVERY;
deliveryType = "CBD - Delivery";
updatePrice();
stdDeliveryGroup.setVisibility(View.GONE);
break;
case R.id.standard_delivery_radio:
// ToDo: Impliment delivery charges if delivering outside of CBD
delivery = STD_DELIVERY;
deliveryType = "Standard Delivery";
stdDeliveryGroup.setVisibility(View.VISIBLE);
// SystemClock.sleep(2000);
break;
}
if (stdDeliveryGroup.getVisibility() == View.VISIBLE) {
// Force measurement since view was "gone" at last measurement.
if (stdDeliveryGroup.getMeasuredHeight() == 0) {
// Only force measurement if the view is gone; otherwise, the normal flow
// will work.
ViewGroup.LayoutParams lp = stdDeliveryGroup.getLayoutParams();
int widthSpec = View.MeasureSpec.makeMeasureSpec(lp.width, View.MeasureSpec.EXACTLY);
int heightSpec = View.MeasureSpec.makeMeasureSpec(lp.height, View.MeasureSpec.EXACTLY);
stdDeliveryGroup.measure(widthSpec, heightSpec);
}
toMove = stdDeliveryGroup.getMeasuredHeight();
}
if (stdDeliveryGroup.getVisibility() == View.GONE) {
toMove = 0;
}
shippingNumber.animate().translationY(toMove);
shippingText.animate().translationY(toMove);
orderButton.animate().translationY(toMove);
totalText.animate().translationY(toMove);
totalNumber.animate().translationY(toMove);
}
});
return myView;
}
constraintLayout.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
constraintLayout.getViewTreeObserver().removeOnPreDrawListener(this);
stdDeliveryGroup.setVisibility(View.GONE);
return false;
}
});