This effect picture:

GitHub:github.com/baiyuliang/…

The disadvantage is that the NestedScrollView nested ViewPager, the effect can be achieved, but the actual application experience seems to be a little poor, the reason can see the blog tail note.

The layout of the first edition:

At first, considering TabLayout and RecyclerView (ViewPager) can slide together, so it is easy to think of the way is to use Scrollview nested in both, the effect is achieved, but Scrollview nested ViewPager drawbacks are obvious!

The second version of this blog is not to solve the problem of Scrollview nested Viewpager, but a different way to implement!

Layout diagram, very simple, just two layers:


      
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f7f7f7"
    android:focusable="true"
    android:focusableInTouchMode="true">

    <LinearLayout
        android:id="@+id/ll_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <net.lucode.hackware.magicindicator.MagicIndicator
            android:id="@+id/magicIndicator"
            android:layout_width="match_parent"
            android:layout_height="35dp"
            android:background="#acddee"
            android:visibility="gone" />

        <com.byl.jdrefresh.v1.CustomViewPager
            android:id="@+id/customViewPager"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </LinearLayout>

    <RelativeLayoutSearch bar./>


</RelativeLayout>
Copy the code

Put the first and second layers (custom JdScrollVIew) in the fragment of Tab1:


      
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.byl.jdrefresh.v2.JdScrollView2
        android:id="@+id/jdScrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>
Copy the code

JdScrollView layout only need to change the original layout of the ViewPager into RecyclerView, can refer to the specific source code!

But this does not solve the TabLayout and the list slide together. !

In fact, it’s a coincidence that the MainActivity has a TabLayout, TabLayout (NestedScrollview nested TabLayout+RecyclerView); when the position of the viewPager ==0, The TabLayout in the MainActivity is hidden, and other pages are displayed. All effects are transferred from the MainActivity to the Tab1Fragment, so that ScrollView nested Viewpager mode is avoided.


      
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rl_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
        android:id="@+id/view"
        android:layout_width="match_parent"
        android:layout_height="180dp"
        android:background="#acddee" />

    <ImageView
        android:id="@+id/iv_ad"
        android:layout_width="match_parent"
        android:layout_height="1000dp"
        android:layout_marginTop="-820dp"
        android:scaleType="centerCrop"
        android:src="@mipmap/bg_ad" />

    <LinearLayout
        android:id="@+id/ll_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_refresh_state"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:gravity="center"
            android:text="Drop-down refresh"
            android:textColor="#dddddd" />

        <net.lucode.hackware.magicindicator.MagicIndicator
            android:id="@+id/magicIndicator"
            android:layout_width="match_parent"
            android:layout_height="35dp" />

        <com.byl.jdrefresh.v2.CustomRecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginHorizontal="15dp"
            android:nestedScrollingEnabled="false" />

    </LinearLayout>

</RelativeLayout>

Copy the code

In addition, this paper added another function on the basis of the original, which can be referred to jingdong APP. That is, after a certain distance is pulled down, the background will automatically expand down to the full screen, and then automatically enter the advertising page:

The solution is to judge the current pulledown distance when the gesture is lifted (ACTION_UP). When the distance exceeds a certain set value, the picture and the overall layout will be in full-screen state within a certain period of time. In fact, ValueAnimator is used. Constantly set the marginTop of the background image and paddingTop of the content:

    case MotionEvent.ACTION_UP:
                if (adScrollDistance > 500) {
                    isInterceptTouch = true;
                    AnimUtils.start(-(int) (marginTop + adScrollDistance), 500.new AnimUtils.OnAnimListener() {
                        @Override
                        public void onUpdate(int value) {
                            layoutAd(marginTop + adScrollDistance + value);
                            ll_content.setPadding(0, (int) (paddingTop + adScrollDistance + AD_START_SCROLL_DISTANCE) + value, 0.0);
                        }

                        @Override
                        public void onEnd(a) {
                            context.startActivity(new Intent(context, AdActivity.class));
                            new Handler().postDelayed(() -> {
                                tv_refresh_state.setText("Drop-down refresh");
                                isInterceptTouch = false;
                                recyclerView.setRefreshing(false);
                                isInterceptScroll = false;
                                REFRESH_STATUS = REFRESH_DONE;
                                layoutAd(marginTop);
                                iv_ad.setImageAlpha(0);
                                if(onPullListener ! =null) onPullListener.onPull(255);
                                ll_content.setPadding(0, paddingTop, 0.0);
                                reset();
                            }, 300); }});return true; }...Copy the code

It is important to note that the height of the background image is not the height of the screen, but the height of the screen plusHeight of this section:

screenHeight = SysUtils.getScreenHeight(context);
topRemainHeight = SysUtils.Dp2Px(context, imageShowHeight) - StatusBarUtil.getStatusBarHeight(context) - SysUtils.Dp2Px(context, 40);//40 is the height of the search bar
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, screenHeight + topRemainHeight);
marginTop = -(screenHeight + topRemainHeight - SysUtils.Dp2Px(context, imageShowHeight));
layoutParams.topMargin = marginTop;
iv_ad.setLayoutParams(layoutParams);
Copy the code

The reason for this is that if you only set the background to screen height, the red box will stick at the bottom and not be completely hidden when the background is fully developed by constantly setting the marginTop to 0. The reason for this is very simple, as shown below:

Arrived at the bottom of the picture, because the red box and at the bottom of the picture is flat, so just outside the leakage, therefore, which requires the above method, the image based on the height of the screen height + red box section height, again, when the background picture full screen so visible content area is moved to the screen, the entire screen is only the background image is visible!

GitHub:github.com/baiyuliang/…