Android运动布局无法相应工作
我不熟悉Android运动布局无法相应工作,android,android-constraintlayout,android-transitions,android-motionlayout,Android,Android Constraintlayout,Android Transitions,Android Motionlayout,我不熟悉motionlayout,一直在关注各种在线教程,希望了解它的工作原理。简而言之,我知道它基本上是为约束集设置动画,你有一个开始和结束,你可以用约束集进一步定制。我有这个布局 我想模仿Lyft的底片 在我的布局中,你要去哪里按钮会随着搜索目的地文本输入淡入而慢慢淡出。底部的recyclerview假设保存了地址,则不会受到影响。我使用标准的底片尝试了这个实现,但是在动画方面遇到了挑战,它有一个奇怪的闪烁,所以我决定使用一个正常视图的运动布局 我的底页布局如下 <com.goog
motionlayout
,一直在关注各种在线教程,希望了解它的工作原理。简而言之,我知道它基本上是为约束集设置动画,你有一个开始和结束,你可以用约束集进一步定制。我有这个布局
我想模仿Lyft的底片
在我的布局中,你要去哪里
按钮会随着搜索目的地文本输入
淡入而慢慢淡出。底部的recyclerview
假设保存了地址
,则不会受到影响。我使用标准的底片尝试了这个实现,但是在动画方面遇到了挑战,它有一个奇怪的闪烁
,所以我决定使用一个正常视图的运动布局
我的底页
布局如下
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/cardChooseAddressBottomSheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
app:shapeAppearance="@style/ShapeAppearanceRoundedLargeTopCorners">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/bottomSheetConstraintLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/swipeUpHandle"
android:layout_width="50dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:background="@drawable/ic_swipe_up_handle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/hiThere"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:text="@string/hi_there"
android:textAppearance="@style/h6_headline"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swipeUpHandle"
/>
<com.google.android.material.button.MaterialButton
android:id="@+id/btnSearch"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="@dimen/medium_margin"
android:gravity="start|center_vertical"
android:letterSpacing="0.0"
android:text="@string/where_are_you_going"
android:textAllCaps="false"
android:textAppearance="@style/subtitle1"
android:textColor="@android:color/darker_gray"
app:backgroundTint="@android:color/white"
app:icon="@drawable/ic_search"
app:iconTint="@android:color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/hiThere"
app:shapeAppearanceOverlay="@style/ShapeAppearanceRoundedMediumAllCorners" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="@+id/addressViews"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnSearch">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/inputOrigin"
style="@style/textInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:hint="@string/search_destination"
android:textColorHint="@android:color/darker_gray"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edtOrigin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:textAppearance="@style/subtitle1"
android:textColor="@android:color/white" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/inputDestination"
style="@style/textInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:hint="@string/search_destination"
android:textColorHint="@android:color/darker_gray"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/inputOrigin">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edtDestination"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:textAppearance="@style/subtitle1"
android:textColor="@android:color/white" />
</com.google.android.material.textfield.TextInputLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="@+id/recyclerAddresses"
android:layout_marginTop="@dimen/medium_margin"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/addressViews"
tools:listitem="@layout/recycler_view_item" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/motionLayout"
app:layoutDescription="@xml/taxi_bottomsheet_scene"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include
layout="@layout/choose_destination_bottom_sheet_layout"/>
</androidx.constraintlayout.motion.widget.MotionLayout>
最后,我的taxi\u bottomsheet\u场景
运动场景是
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
app:constraintSetEnd="@+id/expanded"
app:constraintSetStart="@+id/collapsed"
app:duration="1000">
<OnSwipe
app:touchAnchorId="@+id/btnSearch"
app:touchAnchorSide="top"
app:dragDirection="dragUp"/>
</Transition>
<ConstraintSet android:id="@+id/expanded">
<Constraint
android:id="@+id/cardChooseAddressBottomSheet"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHeight_percent="1"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0" />
<Constraint
android:id="@+id/addressViews"
app:layout_constraintHeight_percent="1"/>
<Constraint
android:id="@+id/btnSearch"
app:layout_constraintHeight_percent="0"/>
</ConstraintSet>
<ConstraintSet android:id="@+id/collapsed">
<Constraint
android:id="@+id/cardChooseAddressBottomSheet"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHeight_percent="0.4"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
<Constraint
android:id="@+id/addressViews"
app:layout_constraintHeight_percent="0.0"/>
<Constraint
android:id="@+id/btnSearch"
app:layout_constraintHeight_percent="0.0"/>
</ConstraintSet>
</MotionScene>
当我启动这个应用程序时,我无法让底部滑动,它根本没有任何反应。但我注意到的一件事是,在添加了app:layoutDescription=“@xml/taxi\u bottomsheet\u scene”
属性后,底部工作表大小更改为我在constraintSetStart
中指定的大小,但addressViews
视图没有更改
所以我的布局看起来像
所以我的问题是,如果我的底部表单没有响应我的滑动
,并且地址视图
在初始状态下消失,我会出什么问题呢?我最终设法使它工作,包括运动布局
和协调布局
。我将只发布协调人
解决方案,因为它很长,而且我没有时间,如果有人需要,请发表评论,我将发布
我创建了3个布局,1。带有地图的主布局
,2。顶部带有“收件人”和“发件人”地址编辑文本的栏
和3。向上滑动并显示顶部栏的底部布局
使用协调布局的解决方案1
顶栏
请注意,我在顶部地址栏上使用了不可见的而不是消失的?这是因为每次我调用GONE
时,根据我的假设,理想情况下布局都会重新计算
,地图会闪烁,为了停止,我不得不使用“不可见”,因为布局没有收缩,相反,它仍然占用相同的空间,但只是不可见
另外请注意,我正在添加paddingcardChooseAddressBottomSheet.getLayoutParams()
这是因为我需要工作表不要深入到topAddressBar
下面,以免隐藏我的recyclerview内容。当前的填充确保recyclerview完全可见,并且它上面的所有其他内容都位于topAddressBar
下面。您是否修复了它?我也在处理同样的情况。但不是用动作布局是的,我做了。我会很快发布答案。好的。谢谢谢谢。@shine_joseph我用MotionLayout
和coordinatorlayout
都达到了同样的效果。MotionLayout使MapFragment
闪烁,但CoordinatorLayout
方法不闪烁。我应该提供哪一个?你可以提供最好的。嗨,你能分享MotionLayout解决方案吗?或者,如果您的代码位于github,您也可以共享github链接。谢谢@AstonioCheck@K.tas
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:layout_marginBottom="@dimen/medium_margin"
app:layout_scrollFlags="noScroll">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/topToolBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navigationIcon="@drawable/ic_arrow_back_black_24dp" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/addressViews"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/topToolBar">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/imgOrigin"
android:layout_width="@dimen/activity_horizontal_margin"
android:layout_height="@dimen/activity_horizontal_margin"
android:layout_marginStart="@dimen/medium_margin"
android:layout_marginEnd="@dimen/medium_margin"
app:layout_constraintBottom_toBottomOf="@+id/inputOrigin"
app:layout_constraintEnd_toStartOf="@+id/inputOrigin"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/inputOrigin"
app:srcCompat="@drawable/ic_origin"
app:tint="@color/colorAccent" />
<View
android:layout_width="2dp"
android:layout_height="0dp"
android:layout_marginTop="@dimen/xsmall_margin"
android:layout_marginBottom="@dimen/xsmall_margin"
android:background="@drawable/accent_to_color_primary_dark__negative_90_gradient"
app:layout_constraintBottom_toTopOf="@+id/imgDestination"
app:layout_constraintEnd_toEndOf="@+id/imgOrigin"
app:layout_constraintStart_toStartOf="@+id/imgOrigin"
app:layout_constraintTop_toBottomOf="@+id/imgOrigin" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/inputOrigin"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:hint="@string/pick_up_location"
android:marqueeRepeatLimit="marquee_forever"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/imgOrigin"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edtOrigin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:inputType="textPostalAddress"
android:singleLine="true"
android:textAppearance="@style/subtitle1" />
</com.google.android.material.textfield.TextInputLayout>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/imgDestination"
android:layout_width="@dimen/activity_horizontal_margin"
android:layout_height="@dimen/activity_horizontal_margin"
android:layout_marginStart="@dimen/medium_margin"
android:layout_marginEnd="@dimen/medium_margin"
app:layout_constraintBottom_toBottomOf="@+id/inputDestination"
app:layout_constraintEnd_toStartOf="@+id/inputDestination"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/inputDestination"
app:srcCompat="@drawable/ic_destination"
app:tint="@color/colorPrimaryDark" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/inputDestination"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:hint="@string/search_destination"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/imgDestination"
app:layout_constraintTop_toBottomOf="@id/inputOrigin">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edtDestination"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:inputType="textPostalAddress"
android:singleLine="true"
android:textAppearance="@style/subtitle1" />
</com.google.android.material.textfield.TextInputLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/cardChooseAddressBottomSheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardBackgroundColor="@color/white"
app:behavior_hideable="false"
app:layout_behavior="@string/bottom_sheet_behavior">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/swipeUpHandle"
android:layout_width="35dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:background="@drawable/ic_swipe_up_handle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/hiThere"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hi_there"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:textAppearance="@style/h6_headline"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/swipeUpHandle" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btnSearch"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:gravity="start|center_vertical"
android:letterSpacing="0.0"
android:text="@string/where_are_you_going"
android:textAllCaps="false"
android:textAppearance="@style/subtitle1"
android:textColor="@android:color/darker_gray"
app:backgroundTint="@android:color/white"
app:icon="@drawable/ic_search"
app:iconSize="@dimen/medium_icon"
app:iconTint="@color/colorAccent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/hiThere"
app:shapeAppearanceOverlay="@style/ShapeAppearanceRoundedMediumAllCorners" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerAddresses"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnSearch" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerSearchAddresses"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@color/white"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btnSearch" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:id="@+id/coordinator"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.67"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imgMapCenter"
android:layout_marginBottom="@dimen/xlarge_margin"
android:visibility="invisible"
android:tint="@color/colorAccent"
app:layout_constraintBottom_toBottomOf="@id/map"
app:layout_constraintEnd_toEndOf="@id/map"
app:layout_constraintStart_toStartOf="@id/map"
app:layout_constraintTop_toTopOf="@id/map"
app:srcCompat="@drawable/ic_destination" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fabMyLocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
app:backgroundTint="@color/white"
app:fabSize="mini"
app:layout_anchor="@id/cardChooseAddressBottomSheet"
app:layout_anchorGravity="top|right"
app:srcCompat="@drawable/ic_origin"
app:tint="@color/colorAccent" />
<include layout="@layout/taxi_fragment_set_destination_top_bar" />
<include layout="@layout/taxi_fragment_bottom_sheet_addresses_layout" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
final private BottomSheetBehavior.BottomSheetCallback addressBottomSheetCallBack = new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
switch (newState) {
case BottomSheetBehavior.STATE_HIDDEN:
break;
case BottomSheetBehavior.STATE_SETTLING:
break;
case BottomSheetBehavior.STATE_EXPANDED:
if (!allPermissionsGranted())
requestForLocationPermissions();
topAddressBar.setVisibility(Visibility.VISIBLE);
fabMyLocation.hide();
break;
case BottomSheetBehavior.STATE_COLLAPSED:
if (!allPermissionsGranted())
requestForLocationPermissions();
topAddressBar.setVisibility(Visibility.INVISIBLE);
fabMyLocation.show();
break;
case BottomSheetBehavior.STATE_DRAGGING:
break;
case BottomSheetBehavior.STATE_HALF_EXPANDED:
break;
}
}
BottomSheetBehavior addressBottomSheetBehavior = BottomSheetBehavior.from(cardChooseAddressBottomSheet);
topAddressBar.post(() -> {
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) cardChooseAddressBottomSheet.getLayoutParams();
layoutParams.height = ((Resources.getSystem().getDisplayMetrics().heightPixels + (int) utils.percentageOf(62, btnSearch.getMeasuredHeight())) - topAddressBar.getMeasuredHeight());
});
addressBottomSheetBehavior.setPeekHeight((int) utils.percentageOf(29, Resources.getSystem().getDisplayMetrics().heightPixels), true);
addressBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
topToolBar.setNavigationOnClickListener(view12 -> {
if (addressBottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED) {
utopAddressBar.setVisibility(INVISIBLE);
addressBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
} else
Navigation.findNavController(view12).navigateUp();
});
addressBottomSheetBehavior.addBottomSheetCallback(addressBottomSheetCallBack);