Прокрутите скрытый вид / макет снизу

Этого я хочу достичь: Введите описание изображения здесь

Я хотел использовать AbsoluteLayout, но он устарел. Поэтому я сделал RelativeLayout под синим представлением на изображении выше, а затем поместил все в ScrollView, но скрытый вид все еще находится на «голубом» изображении, а не ниже. Кроме того, экран прокручивается, но скрытая часть просто вырезана, и вместо этого я вижу фоновый фон моего приложения.

Есть идеи?

EDIT: моя текущая попытка:

<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:fillViewport="true" android:layout_height="wrap_content"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:animateLayoutChanges="true" android:orientation="vertical" > <ImageView android:id="@+id/imageView" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@drawable/imageView" /> <LinearLayout android:id="@+id/centerHolder" android:layout_width="300dp" android:layout_height="wrap_content" android:layout_centerInParent="true" android:orientation="vertical" > ..... ..... </LinearLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="1000dp" android:layout_below="@id/main_holder" android:background="@color/black_color"> </RelativeLayout> </RelativeLayout> </ScrollView> 

Я беру это из моего проекта, который отображает RecyclerView где вы можете добавлять данные, если вы нажимаете на строку, потому что щелчок «открывает» нижний лист.

 <android.support.design.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent"> <RelativeLayout android:id="@+id/rl_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".view.fragment.BlockFragment"> <include android:id="@+id/ll_header" layout="@layout/layout_header_names" /> <include android:id="@+id/divider_header" layout="@layout/layout_divider_horizontal" android:layout_width="match_parent" android:layout_height="1dp" android:layout_below="@+id/ll_header" /> <android.support.v7.widget.RecyclerView android:id="@+id/rv_block" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/divider_footer" android:layout_below="@+id/divider_header" /> <include android:id="@+id/divider_footer" layout="@layout/layout_divider_horizontal" android:layout_width="match_parent" android:layout_height="1dp" android:background="#767676" android:layout_above="@+id/ll_footer" /> <include android:id="@+id/ll_footer" layout="@layout/layout_footer_score" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:layout_alignParentBottom="true"/> </RelativeLayout> <!-- Here comes my bottom sheet. It is wrapped inside a FrameLayout, because an include cannot have a behaviour. The included layout is every layout you can imagine - mine is a RelativeLayout with two EditTexts for example. The layout_behaviour is the second important line. --> <FrameLayout android:id="@+id/container_bottom_sheet" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#e3e3e3" app:layout_behavior="android.support.design.widget.BottomSheetBehavior"> <include layout="@layout/layout_bottom_sheet"/> </FrameLayout> </android.support.design.widget.CoordinatorLayout> 1 <android.support.design.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent"> <RelativeLayout android:id="@+id/rl_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".view.fragment.BlockFragment"> <include android:id="@+id/ll_header" layout="@layout/layout_header_names" /> <include android:id="@+id/divider_header" layout="@layout/layout_divider_horizontal" android:layout_width="match_parent" android:layout_height="1dp" android:layout_below="@+id/ll_header" /> <android.support.v7.widget.RecyclerView android:id="@+id/rv_block" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/divider_footer" android:layout_below="@+id/divider_header" /> <include android:id="@+id/divider_footer" layout="@layout/layout_divider_horizontal" android:layout_width="match_parent" android:layout_height="1dp" android:background="#767676" android:layout_above="@+id/ll_footer" /> <include android:id="@+id/ll_footer" layout="@layout/layout_footer_score" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:layout_alignParentBottom="true"/> </RelativeLayout> <!-- Here comes my bottom sheet. It is wrapped inside a FrameLayout, because an include cannot have a behaviour. The included layout is every layout you can imagine - mine is a RelativeLayout with two EditTexts for example. The layout_behaviour is the second important line. --> <FrameLayout android:id="@+id/container_bottom_sheet" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#e3e3e3" app:layout_behavior="android.support.design.widget.BottomSheetBehavior"> <include layout="@layout/layout_bottom_sheet"/> </FrameLayout> </android.support.design.widget.CoordinatorLayout> 1 <android.support.design.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent"> <RelativeLayout android:id="@+id/rl_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".view.fragment.BlockFragment"> <include android:id="@+id/ll_header" layout="@layout/layout_header_names" /> <include android:id="@+id/divider_header" layout="@layout/layout_divider_horizontal" android:layout_width="match_parent" android:layout_height="1dp" android:layout_below="@+id/ll_header" /> <android.support.v7.widget.RecyclerView android:id="@+id/rv_block" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/divider_footer" android:layout_below="@+id/divider_header" /> <include android:id="@+id/divider_footer" layout="@layout/layout_divider_horizontal" android:layout_width="match_parent" android:layout_height="1dp" android:background="#767676" android:layout_above="@+id/ll_footer" /> <include android:id="@+id/ll_footer" layout="@layout/layout_footer_score" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:layout_alignParentBottom="true"/> </RelativeLayout> <!-- Here comes my bottom sheet. It is wrapped inside a FrameLayout, because an include cannot have a behaviour. The included layout is every layout you can imagine - mine is a RelativeLayout with two EditTexts for example. The layout_behaviour is the second important line. --> <FrameLayout android:id="@+id/container_bottom_sheet" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#e3e3e3" app:layout_behavior="android.support.design.widget.BottomSheetBehavior"> <include layout="@layout/layout_bottom_sheet"/> </FrameLayout> </android.support.design.widget.CoordinatorLayout> 

Для самого поведения вам необходимо получить FrameLayout ( View с app:layout_behavior="android.support.design.widget.BottomSheetBehavior" ).

 private BottomSheetBehavior bottomSheetBehavior; bottomSheetBehavior = BottomSheetBehavior.from((FrameLayout)findViewById(R.id.container_bottom_sheet); //for the sheet to "peek": bottomSheetBehavior.setPeekHeight(200); //now you can set the states: bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); 

Также возможно установить BottomSheetCallback() в котором вы можете получить все изменения состояния, а также slideOffset!

  bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { @Override public void onStateChanged(@NonNull View bottomSheet, int newState) { switch (newState) { case BottomSheetBehavior.STATE_DRAGGING: case BottomSheetBehavior.STATE_EXPANDED: break; case BottomSheetBehavior.STATE_COLLAPSED: default: } } @Override public void onSlide(@NonNull View bottomSheet, float slideOffset) { } }); 

Я думаю, вы должны просто использовать LinearLayout для обертки ImageView и других макетов.

Отредактирован ответ на основе комментариев.

 <?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:fillViewport="true" android:layout_height="wrap_content"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:animateLayoutChanges="true" android:orientation="vertical" > <LinearLayout android:id="@+id/centerHolder" android:layout_width="300dp" android:layout_height="wrap_content" android:layout_centerInParent="true" android:orientation="vertical" > ..... ..... </LinearLayout> <ImageView android:id="@+id/imageView" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@drawable/imageView" android:layout_alignParentTop="true" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="1000dp" android:layout_below="@+id/centerHolder" android:background="@color/black_color"> </RelativeLayout> </RelativeLayout> </ScrollView> 

Просто замените ScrollView на NestedScrollView

Пример:

 <android.support.v4.widget.NestedScrollView 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:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> 

Я понял, что вам нужно что-то подобное, просто протестируйте его, просто скопируйте два файла и посмотрите, как это работает.

 import android.animation.ObjectAnimator; import android.content.Context; import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.TypedValue; import android.view.MotionEvent; import android.view.View; import android.widget.LinearLayout; import android.widget.ScrollView; public class MainActivity extends AppCompatActivity { LinearLayout movableLL; boolean mDragLockGained; float initialTouchPoint; // int cutoffElevation; boolean inAnimation; ScrollView scrollView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); scrollView = (ScrollView) findViewById(R.id.scrollView); movableLL = (LinearLayout) findViewById(R.id.mobileLL); movableLL.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (inAnimation) return true; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mDragLockGained = true; initialTouchPoint = event.getRawY(); break; case MotionEvent.ACTION_MOVE: performTranslation(event); initialTouchPoint = event.getRawY(); break; case MotionEvent.ACTION_UP: mDragLockGained = false; performSettlingAnimation(); break; } return true; } }); } private void performTranslation(MotionEvent event) { float newDelta = event.getRawY() - initialTouchPoint; float currentY = movableLL.getTranslationY(); if (currentY + newDelta > 0) { movableLL.setTranslationY(currentY + newDelta); if (scrollView.getTranslationY() + newDelta < 0){ } scrollView.setTranslationY(scrollView.getTranslationY() + newDelta); } else { movableLL.setTranslationY(currentY); scrollView.setTranslationY(scrollView.getTranslationY()); } } final int SETTLE_ANIMATION_DURATION = 300; private void performSettlingAnimation() { ObjectAnimator animLl = ObjectAnimator.ofFloat(movableLL, "translationY", movableLL.getTranslationY(), convertDpToPixels(this, 150)); inAnimation = true; animLl.setDuration(SETTLE_ANIMATION_DURATION); animLl.start(); new Handler().postDelayed(new Runnable() { @Override public void run() { inAnimation = false; } }, SETTLE_ANIMATION_DURATION);//use animationListener here as a best practice and toggle values in //on animation start and cancel/finish ObjectAnimator animSv = ObjectAnimator.ofFloat(scrollView, "translationY", scrollView.getTranslationY() , 0); animSv.setDuration(SETTLE_ANIMATION_DURATION); animSv.start(); } public static int convertDpToPixels(Context context, int dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics() ); } } 

И xml ……

  <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ScrollView android:id="@+id/scrollView" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="200dp" android:gravity="center" android:text="Hello There" /> <TextView android:layout_width="match_parent" android:layout_height="200dp" android:gravity="center" android:text="Hello Again" /> <TextView android:layout_width="match_parent" android:layout_height="200dp" android:gravity="center" android:text="WhatsUp" /> <TextView android:layout_width="match_parent" android:layout_height="200dp" android:gravity="center" android:text="See ya" /> </LinearLayout> </ScrollView> <LinearLayout android:id="@+id/mobileLL" android:layout_width="match_parent" android:layout_height="300dp" android:translationY="150dp" android:layout_gravity="bottom" android:background="@android:color/white" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:background="#99ff0000" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:background="#990000ff" /> </LinearLayout> 

Пожалуйста, дайте мне знать, если я что-то пропустил.

Для этого наилучшим способом является использование BottomSheet из библиотеки поддержки дизайна с моей точки зрения.

 <?xml version="1.0" encoding="utf-8"?><android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/main_content" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true"> <ScrollView android:layout_width="match_parent" android:layout_height="wrap_content" android:fillViewport="true"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:animateLayoutChanges="true" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="1000dp" android:background="@android:color/white"> <!-- other layout --> </RelativeLayout> </RelativeLayout> </ScrollView> <FrameLayout android:id="@+id/bottom_sheet" android:layout_width="match_parent" android:layout_height="wrap_content" app:behavior_peekHeight="120dp" app:layout_behavior="android.support.design.widget.BottomSheetBehavior"> <View android:layout_width="match_parent" android:layout_height="240dp" android:background="@android:color/darker_gray" /> </FrameLayout> </android.support.design.widget.CoordinatorLayout> 

Также можно комбинировать его с вашим собственным положением CoordinatorLayout, чтобы изменить положение прокрутки для вашего прокрутки, если это необходимо.