从底部滚动隐藏的视图/布局

时间:2016-05-02 20:20:17

标签: android layout scrollview

这是我想要实现的目标: enter image description here

我想使用AbsoluteLayout但不推荐使用它。 所以我在上图中的蓝色视图下面创建了一个RelativeLayout,然后将所有内容放在ScrollView中,但隐藏的视图仍然在蓝色视图上,而不是在它下面。此外,屏幕滚动,但隐藏的部分只是剪切,而是我看到我的应用程序的默认背景..

有什么想法吗?

编辑: 我目前的尝试:

<?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>

5 个答案:

答案 0 :(得分:3)

我认为您应该使用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>

答案 1 :(得分:3)

我从我的一个项目中获取此信息,该项目显示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>

对于行为本身,您需要获取FrameLayoutViewapp: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) {

        }
    });

答案 2 :(得分:2)

只需将您的if (savedInstanceState == null) { // only create fragment if activity is started for the first time mFragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction(); FragmentOne fragment = new FragmentOne(); fragmentTransaction.add(R.id.fragment_container, fragment); fragmentTransaction.commit(); } else { // do nothing - fragment is recreated automatically } 替换为ScrollView

即可

示例:

NestedScrollView

答案 3 :(得分:2)

我意识到你需要这样的东西,只是测试一下,只需复制两个文件,看看它是如何工作的。

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>

如果我错过了什么,请告诉我。

答案 4 :(得分:0)

出于此目的,最好的方法是从我的角度使用Design Support Library中的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行为相结合,以更改滚动视图的滚动位置。