简体   繁体   中英

How to make ViewPager scroll and making header image as a collapsing toolbar?

I have a recipe fragment that has a header image and a ViewPager, and I'm facing two problems with the current design:

1- The tabs content are not scrolling vertically unless I press on the header image and start scrolling. What I mean by this is that if I swipe vertically on the header image the view will scroll. BUT if I try to swipe vertically from the text area it doesn't scroll. (I have an image below)

2- The header image is not all the way up to replace the toolbar like the current version Google Play Store displays apps like the the first screenshot below, and the second screenshot is how my app looks like.

Google Play如何显示应用

我的应用现在的样子

Here is my my fragment_recipe.xml :

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

<android.support.design.widget.AppBarLayout
    android:id="@+id/tab_app_bar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fitsSystemWindows="true"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:layout_scrollFlags="scroll|exitUntilCollapsed">

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/tab_collapse_toolbar"
        android:layout_width="match_parent"
        android:layout_marginTop="25dp"
        android:layout_height="256dp"
        android:fitsSystemWindows="true"
        app:contentScrim="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">

        <ImageView
            android:id="@+id/recipe_header"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/header"
            android:fitsSystemWindows="true"
            android:scaleType="centerCrop"
            app:layout_collapseMode="parallax"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            />

        <android.widget.Toolbar
            android:id="@+id/tab_toolbar"
            android:layout_width="match_parent"
            android:layout_height="104dp"
            android:gravity="top"
            android:minHeight="?attr/actionBarSize"
            app:layout_collapseMode="pin"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:titleMarginTop="13dp" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:textStyle="bold"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:layout_gravity="bottom"
            app:layout_scrollFlags="scroll|enterAlways"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            app:tabIndicatorColor="@android:color/white" />
    </android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>

<android.support.v4.view.ViewPager
    android:id="@+id/viewpager"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:tabMode="scrollable"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>

And here is my FargmentRecipe.java :

import android.annotation.TargetApi;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import java.util.ArrayList;
import java.util.List;
import mamoonbraiga.MealMate.activities.MainActivity;
import mamoonbraiga.MealMate.extras.Recipe;
import mamoonbraiga.MealMate.network.VolleySingleton;
import mamoonbraiga.poodle_v3.R;


public class FragmentRecipe extends Fragment{

private ImageView header;
private VolleySingleton volleySingleton = VolleySingleton.getsInstance();;
private ImageLoader imageLoader=volleySingleton.getImageLoader();;
private Bundle bundle;

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){


    final View view = inflater.inflate(R.layout.fragment_recipe, container, false);
    MainActivity mainActivity = (MainActivity) getActivity();
    header = (ImageView) view.findViewById(R.id.recipe_header);  //setting up the header
    bundle = mainActivity.getSavedData();
    Recipe recipe = bundle.getParcelable("recipe");

    //load the header
    loadHeader(recipe);
    ((MainActivity) getActivity()).getSupportActionBar().hide();
    Toolbar toolbar = (Toolbar) view.findViewById(R.id.tab_toolbar);
    mainActivity.setActionBar(toolbar);
    mainActivity.getActionBar().setDisplayHomeAsUpEnabled(true);

    /** view pager and tab setup **/
    final ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager);
    viewPager.setVerticalScrollBarEnabled(true);
    setUpViewPager(viewPager);
    final TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tabs);
    tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
    tabLayout.setSelectedTabIndicatorColor(Color.parseColor("#FF5722"));
    tabLayout.setupWithViewPager(viewPager);
    /** view pager and tab setup **/

    return view;
}

private void loadHeader(Recipe recipe) {
    imageLoader.get(recipe.getImageUrl(), new ImageLoader.ImageListener() {
        @Override
        public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
            Drawable d = new BitmapDrawable(getResources(), response.getBitmap());
            header.setBackground(d);
        }

        @Override
        public void onErrorResponse(VolleyError error) {

        }
    });
}

private void showToast(String msg) {

    Toast.makeText(getContext(), msg, Toast.LENGTH_SHORT).show();
}

private void setUpViewPager(ViewPager viewPager) {

    ViewPagerAdapter adapter = new ViewPagerAdapter(getActivity().getSupportFragmentManager());
    adapter.addFrag(new FragmentDescription(), "Description");
    adapter.addFrag(new FragmentIngredients(), "Ingredients");
    adapter.addFrag(new FragmentNutrition(), "Nutrition");
    viewPager.setAdapter(adapter);

}

static class ViewPagerAdapter extends FragmentStatePagerAdapter{


    private final List<String> mFragmentTitleList = new ArrayList<>();
    private final List<Fragment> mFragmentList = new ArrayList<>();

    public ViewPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    public void addFrag(Fragment fragment, String title){
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }
    @Override
    public CharSequence getPageTitle(int position){
        return mFragmentTitleList.get(position);
    }

}
@Override
public void onPause(){
    super.onPause();
    ((MainActivity) getActivity()).getSupportActionBar().show();
}

}

1) I don't have your fragments layouts xml (FragmentDescription, FragmentIngredients and FragmentNutrition layouts) but I am guessing your are using ScrollView instead of NestedScrollView. Try this at the root of your nested fragments: <android.support.v4.widget.NestedScrollView>

2) When your header collapse, do you still have the black status bar? If so, you have to add transparency to your status bar.So in your theme: <item name="android:statusBarColor">#80000000</item> (here I am using a dark transparent color, to make it look nicer, but it's up to you)

Note also that you cannot get full transparent status bar on pre-Lollipop devices.

2bis) if you already have a transparent statusbar (you see the image passing behind after a bit of scrolling up), then you can try this hack:

    <ImageView
        android:id="@+id/recipe_header"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/header"
        android:layout_marginTop="-24dp"
        android:fitsSystemWindows="true"
        android:scaleType="centerCrop"
        app:layout_collapseMode="parallax"
        app:layout_scrollFlags="scroll|exitUntilCollapsed"
        />

This will move the image up by the height of the status bar, thus making it fit with the top of the window. There is probably a proper solution, but it is the one I am using at the moment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM