Android嵌套式ViewPager,垂直ViewPager

本文详细介绍了如何在Android中实现嵌套ViewPager,包括一个垂直滚动的ViewPager。教程通过创建一个类似Inshorts和Flipboard的应用,展示了如何在垂直ViewPager中嵌套一个水平滑动的ViewPager,以及如何在页面切换时添加动画效果。
摘要由CSDN通过智能技术生成

In this tutorial, we’ll be implementing android nested ViewPager i.e a ViewPager within a ViewPager. Also, we’ll discuss and implement Vertical ViewPager too. We’ll be developing an application that replicates the swiping feature present in applications like Inshorts and Flipboard.

在本教程中,我们将实现android嵌套的ViewPager,即ViewPager中的ViewPager。 另外,我们还将讨论和实现Vertical ViewPager。 我们将开发一个应用程序,该应用程序可以复制InshortsFlipboard等应用程序中存在的滑动功能。

Android巢状ViewPager (Android Nested ViewPager)

If you’ve used the above-mentioned applications, you would have realized how easy it is to browse through different contents by just swiping up or down the current page.

如果您使用了上述应用程序,您将已经意识到,只需向上或向下滑动当前页面即可浏览不同内容。

The underlying view used to create such features is a ViewPager.

用于创建此类功能的基础视图是ViewPager

To brief up, ViewPagers use a PagerAdapter that adds pages (generally in the form of Fragment views) to our ViewPager.

简而言之,ViewPagers使用PagerAdapter将页面(通常以Fragment视图的形式)添加到我们的ViewPager。

By default, ViewPager has a built-in swipe gesture to swipe left or right. There’s an interface named PageTransformer that gets invoked while a scrolling on a ViewPager happens.

默认情况下, ViewPager具有内置的滑动手势,可以向左或向右滑动。 这里有一个接口命名PageTransformer ,同时在ViewPager滚动碰巧被调用。

The PagerTransform interface contains the following public method that can be overridden and implemented.

PagerTransform接口包含以下可以重写和实现的公共方法。

void transformPage (View page, float position)
  • page: The current view on which the transformation would be applied.

    page :将在其上应用转换的当前视图。
  • position: Position of the page relative to the current front-and-center position of the pager. 0 is front and center. 1 is one full page position to the right, and -1 is one-page position to the left.

    position :页面相对于寻呼机当前当前位置的位置。 0是前面和中间。 1是右边的一整页位置,而-1是左边的一整页位置。

Nested ViewPager is simply a ViewPager wrapped around another ViewPager.

嵌套ViewPager只是将ViewPager包裹在另一个ViewPager周围。

What does this mean?

这是什么意思?

It means that we have a parent ViewPager in each page of a fragment. The child ViewPager would be hosted inside each of the above fragments.

这意味着我们在片段的每个页面中都有一个父ViewPager。 子ViewPager将托管在上述每个片段中。

In the following application, our parent View Pager would we a vertical swiping one. The child View Pager would be the default one that swipes/scrolls horizontally.

在以下应用程序中,我们的父级View Pager将使我们垂直滑动。 子级View Pager是默认的控件,它可以水平滑动/滚动。

We’ll be developing an application that holds a list of Android Tutorials with their descriptions in a Vertical ViewPager. On swiping right, the tutorial would be displayed in a WebView.

我们将开发一个应用程序,该应用程序在Vertical ViewPager中包含Android教程列表及其说明。 向右滑动,该教程将显示在WebView中

Android巢状ViewPager专案 (Android Nested ViewPager Project)

Create a new project in Android Studio and select the Tabbed Activity template from the below screen.

android nested viewpager template

在Android Studio中创建一个新项目,然后从下面的屏幕中选择Tabbed Activity模板。

We will see a MainActivity.java class generated as shown below.

我们将看到生成的MainActivity.java类,如下所示。

package com.journaldev.swipeviewpagerinshorts;

import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
   
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
  
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    /**
     * The {@link android.support.v4.view.PagerAdapter} that will provide
     * fragments for each of the sections. We use a
     * {@link FragmentPagerAdapter} derivative, which will keep every
     * loaded fragment in memory. If this becomes too memory intensive, it
     * may be best to switch to a
     * {@link android.support.v4.app.FragmentStatePagerAdapter}.
     */
    private SectionsPagerAdapter mSectionsPagerAdapter;

    /**
     * The {@link ViewPager} that will host the section contents.
     */
    private ViewPager mViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.container);
        mViewPager.setAdapter(mSectionsPagerAdapter);

      FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
      fab.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View view) {
              Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                      .setAction("Action", null).show();
          }
      });
      
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    /**
     * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
     * one of the sections/tabs/pages.
     */
    public class SectionsPagerAdapter extends FragmentPagerAdapter {

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

        @Override
        public Fragment getItem(int position) {
            // getItem is called to instantiate the fragment for the given page.
            // Return a PlaceholderFragment (defined as a static inner class below).
            return PlaceholderFragment.newInstance(position + 1);
        }

        @Override
        public int getCount() {
            // Show 3 total pages.
            return 3;
        }
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {
        /**
         * The fragment argument representing the section number for this
         * fragment.
         */
        private static final String ARG_SECTION_NUMBER = "section_number";

        /**
         * Returns a new instance of this fragment for the given section
         * number.
         */
        public static PlaceholderFragment newInstance(int sectionNumber) {
            PlaceholderFragment fragment = new PlaceholderFragment();
            Bundle args = new Bundle();
            args.putInt(ARG_SECTION_NUMBER, sectionNumber);
            fragment.setArguments(args);
            return fragment;
        }

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);
            TextView textView = (TextView) rootView.findViewById(R.id.section_label);
            textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
            return rootView;
        }
    }
}

Alongside the activity, the class holds the Adapter and Fragment classes as well. This basic template displays a text on each of the pages in a ViewPager. Let’s look at the project structure before we begin with our implementation.

除活动外,该类还包含Adapter和Fragment类。 这个基本模板在ViewPager的每个页面上显示文本。 在开始实施之前,让我们看一下项目结构。

Android嵌套ViewPager项目结构 (Android Nested ViewPager Project Structure)

Add the Internet permission in the AndroidManifest.xml file in the manifest tag.

在清单标记的AndroidManifest.xml文件中添加Internet权限。

<uses-permission android:name="android.permission.INTERNET"/>
  • MainActivity – That holds the parent ViewPager, namely the VerticalViewPager. Invokes the ParentViewPagerAdapter that creates instances of ParentFragment

    MainActivity –包含父ViewPager,即VerticalViewPager 。 调用ParentViewPagerAdapter创建的实例ParentFragment
  • VerticalViewPager – Contains a custom implementation of ViewPager that scrolls vertically. The pages hold a ParentFragment view which is supplied by ParentViewPagerAdapter.

    VerticalViewPager –包含ViewPager的自定义实现,该实现可垂直滚动。 这些页面包含由ParentViewPagerAdapter提供的ParentFragment视图。
  • ParentFragment – It’s present inside the VerticalViewPager. It holds another ViewPager and it’s adapter code is in the file ChildViewPagerAdapter. Fragment’s layout is defined in fragment_parent.xml.

    ParentFragment –它存在于VerticalViewPager 。 它包含另一个ViewPager,其适配器代码在文件ChildViewPagerAdapter 。 Fragment的布局在fragment_parent.xml定义。
  • ChildViewPagerAdapter – Contains the implementation of nested ViewPager. It holds and supplies ChildFragment‘s to the ParentFragment.

    ChildViewPagerAdapter –包含嵌套ViewPager的实现。 它持有并提供ChildFragmentParentFragment
  • ChildFragment – Contains the UI that you’ll see. Layout file : fragment_child.xml

    ChildFragment –包含您将看到的UI。 布局文件: fragment_child.xml
  • DataModel – Contains the data that’s supplied to the ChildFragment.

    DataModel –包含提供给ChildFragment的数据。

Android嵌套式ViewPager,垂直ViewPager代码 (Android Nested ViewPager, Vertical ViewPager Code)

The code for the VerticalViewPager.java class is given below:

下面给出了VerticalViewPager.java类的代码:

package com.journaldev.swipeviewpagerinshorts;

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class VerticalViewPager extends ViewPager {

    public VerticalViewPager(Context context) {
        super(context);
        init();
    }

    public VerticalViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        setPageTransformer(true, new VerticalPageTransformer());
        setOverScrollMode(OVER_SCROLL_NEVER);
    }

    private class VerticalPageTransformer implements ViewPager.PageTransformer {
        @Override
        public void transformPage(View view, float position) {

            if (position < -1) { // [-Infinity,-1)
                // This page is way off-screen to the left.
                view.setAlpha(0);

            } else if (position <= 1) { // [-1,1]
                view.setAlpha(1);

                // Counteract the default slide transition
                view.setTranslationX(view.getWidth() * -position);

                //set Y position to swipe in from top
                float yPosition = position * view.getHeight();
                view.setTranslationY(yPosition);

            } else { // (1,+Infinity]
                // This page is way off-screen to the right.
                view.setAlpha(0);
            }

        }
    }

    /**
     * Swaps the X and Y coordinates of your touch event.
     */
    private MotionEvent swapXY(MotionEvent ev) {
        float width = getWidth();
        float height = getHeight();

        float newX = (ev.getY() / height) * width;
        float newY = (ev.getX() / width) * height;

        ev.setLocation(newX, newY);

        return ev;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev){
        boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
        swapXY(ev);
        return intercepted;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return super.onTouchEvent(swapXY(ev));
    }
}

setOverScrollMode(OVER_SCROLL_NEVER) is used to prevent over scrolling.

setOverScrollMode(OVER_SCROLL_NEVER)用于防止过度滚动。

As we’d discussed before, we create a custom implementation of PageTransformer class where instead of translating the view horizontally using translationX, we do so vertically using translationY. Same is done for motion events when the user swipes on the screen.

正如我们之前讨论的那样,我们创建了一个PageTransformer类的自定义实现,该方法不是使用translationX水平translationX视图,而是使用translationX垂直translationY视图。 当用户在屏幕上滑动时,动作事件也是如此。

The code for DataModel.java is given below.

下面给出了DataModel.java的代码。

package com.journaldev.swipeviewpagerinshorts;

public class DataModel {

    public String title, description, url;

    public DataModel(String title, String description, String url) {
        this.title = title;
        this.description = description;
        this.url = url;
    }
}

The code of the activity_main.xml layout file is given below.

下面给出了activity_main.xml布局文件的代码。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.journaldev.swipeviewpagerinshorts.VerticalViewPager
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorPrimaryDark" />


</RelativeLayout>

It hosts a VerticalViewPager only, which will in turn host the Parent Fragment.

它仅承载VerticalViewPager ,而后者随后将承载父片段。

The code of the MainActivity.java class is given below.

MainActivity.java类的代码如下。

package com.journaldev.swipeviewpagerinshorts;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity implements ParentFragment.ToggleVerticalViewPagerScrolling {

    private ParentViewPagerAdapter verticalPagerAdapter;
    private VerticalViewPager verticalViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ArrayList<DataModel> dataModels = new ArrayList<>();
        dataModels.add(new DataModel("Android Volley Tutorial", getString(R.string.volley_description), getString(R.string.volley_url)));
        dataModels.add(new DataModel("Android Dagger 2", getString(R.string.dagger_description), getString(R.string.dagger_url)));
        dataModels.add(new DataModel("Android Geocoder Reverse Geocoding", getString(R.string.geocoder_description), getString(R.string.geocoder_url)));
        dataModels.add(new DataModel("Android Notification Direct Reply", getString(R.string.notification_description), getString(R.string.notification_url)));
        dataModels.add(new DataModel("RecyclerView Android with Dividers and Contextual Toolbar", getString(R.string.recyclerview_description), getString(R.string.recyclerview_url)));


        verticalPagerAdapter = new ParentViewPagerAdapter(getSupportFragmentManager(), dataModels);
        verticalViewPager = findViewById(R.id.container);
        verticalViewPager.setAdapter(verticalPagerAdapter);

    }

    @Override
    public void trigger(int page) {
        if (page == 1) {
            verticalViewPager.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    return true;
                }
            });
        } else {
            verticalViewPager.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    return false;
                }
            });
        }
    }
}

Things to note:

注意事项:

  • The VerticalViewPager’s adapter, namely ParentViewPagerAdapter is loaded with the data.

    VerticalViewPager的适配器,即ParentViewPagerAdapter随数据ParentViewPagerAdapter加载。
  • The trigger method is overridden from an interface defined in the ParentFragment class. It’s invoked by the ParentFragment whenever a page is changed. Its goal is to disable VerticalViewPager from scrolling/swiping when the Nested ViewPager is showing the second page(since the second page holds a WebView) that we’ll be seeing shortly.

    trigger方法从ParentFragment类中定义的接口覆盖。 每当页面更改时, ParentFragment都会调用它。 它的目标是在Nested ViewPager显示第二页时(因为第二页包含WebView),从而禁止VerticalViewPager滚动/滑动。

Note: To avoid long strings in the class, we’ve defined them in the strings.xml resources file in our project:

android viewpager string resources

注意 :为了避免在类中使用长字符串,我们在项目的strings.xml资源文件中定义了它们:

Code for the ParentViewPagerAdapter.java class is given below.

ParentViewPagerAdapter.java类的代码如下。

package com.journaldev.swipeviewpagerinshorts;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

import java.util.ArrayList;

public class ParentViewPagerAdapter extends FragmentPagerAdapter {

    ArrayList<DataModel> dataModels = new ArrayList<>();

    public ParentViewPagerAdapter(FragmentManager fm, ArrayList<DataModel> dataModels) {
        super(fm);
        this.dataModels = dataModels;
    }

    @Override
    public Fragment getItem(int position) {
        return ParentFragment.newInstance(dataModels.get(position));

    }

    @Override
    public int getCount() {
        return 5;
    }
}

The adapter creates a new ParentFragment class for each page. In total 5 pages for each of the DataModel elements.

适配器为每个页面创建一个新的ParentFragment类。 每个DataModel元素总共5页。

The layout for the ParentFragment class is defined in fragment_parent.xml file as shown below.

如下所示,在fragment_parent.xml文件中定义了ParentFragment类的布局。

<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:id="@+id/rl"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorPrimaryDark">

    <android.support.v4.view.ViewPager
        android:id="@+id/nestedViewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

The ParentFragment class holds the Nested ViewPager.

ParentFragment类保存嵌套的ViewPager。

package com.journaldev.swipeviewpagerinshorts;


import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;


public class ParentFragment extends Fragment {


    ViewPager nestedViewPager;
    Activity mActivity;
    ToggleVerticalViewPagerScrolling tv;

    public ParentFragment() {
    }

    public static ParentFragment newInstance(DataModel dataModel) {
        ParentFragment fragment = new ParentFragment();
        Bundle args = new Bundle();
        args.putString("title", dataModel.title);
        args.putString("description", dataModel.description);
        args.putString("url", dataModel.url);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_parent, container, false);


        String title = getArguments().getString("title");
        String description = getArguments().getString("description");
        String url = getArguments().getString("url");
        DataModel model = new DataModel(title, description, url);
        nestedViewPager = rootView.findViewById(R.id.nestedViewPager);
        nestedViewPager.setAdapter(new ChildViewPagerAdapter(getChildFragmentManager(), model));


        nestedViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                tv.trigger(position);
            }

            @Override
            public void onPageSelected(int position) {
                Log.d("API123", "onPageSelected " + position);
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

        return rootView;
    }

    public interface ToggleVerticalViewPagerScrolling {
        void trigger(int page);

    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        if (context instanceof Activity) {
            mActivity = (Activity) context;
        }

        try {
            tv = (ToggleVerticalViewPagerScrolling) mActivity;
        } catch (ClassCastException e) {
            throw new ClassCastException("Error in retrieving data. Please try again");
        }
    }
}

Things to note:

注意事项:

  • Each ParentFragment.java class holds a Nested ViewPager.

    每个ParentFragment.java类都有一个嵌套的ViewPager。
  • The ChildViewPagerAdapter creates a nested fragment (ChildFragment) instance for each page.

    ChildViewPagerAdapter为每个页面创建一个嵌套的片段(ChildFragment)实例。
  • The Nested ViewPager would hold two pages(ChildFragment instances) only. The first would contain the title and description of the tutorial. The second page would show the tutorial in a WebView.

    嵌套ViewPager将仅容纳两个页面(ChildFragment实例)。 第一个将包含本教程的标题和说明。 第二页将在WebView中显示该教程。
  • addOnPageChangeListener callback is used to determine the current page index.

    addOnPageChangeListener回调用于确定当前页面索引。
  • interface ToggleVerticalViewPagerScrolling contains the method trigger. The trigger method passes the relevant page index to the MainActivity. Read communicating data from fragments

    interface ToggleVerticalViewPagerScrolling包含方法trigger 。 触发方法将相关页面索引传递给MainActivity从片段读取通信数据
  • If the page index is 2 i.e. the WebView UI, the VerticalViewPager swiping is disabled.

    如果页面索引为2,即WebView UI,则禁用VerticalViewPager滑动。

The code for the ChildViewPagerAdapter.java class is given below.

下面给出了ChildViewPagerAdapter.java类的代码。

package com.journaldev.swipeviewpagerinshorts;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

public class ChildViewPagerAdapter extends FragmentPagerAdapter {


    DataModel model;

    public ChildViewPagerAdapter(FragmentManager fm, DataModel model) {
        super(fm);
        this.model = model;
    }

    @Override
    public int getCount() {
        return 2;
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return ChildFragment.newInstance(model, false);
            case 1:
                return ChildFragment.newInstance(model, true);
            default:
                return ChildFragment.newInstance(model, true);
        }
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return "Child Fragment " + position;
    }

}

The code for the layout fragment_child.xml is given below.

下面给出布局fragment_child.xml的代码。

<android.support.v7.widget.CardView xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginBottom="@dimen/activity_vertical_margin"
    android:layout_marginEnd="@dimen/activity_horizontal_margin"
    android:layout_marginStart="@dimen/activity_horizontal_margin"
    android:layout_marginTop="@dimen/activity_vertical_margin"
    app:cardCornerRadius="8dp"
    app:cardElevation="8dp"
    app:cardPreventCornerOverlap="true"
    app:cardUseCompatPadding="true">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <WebView
            android:id="@+id/webView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone" />

        <RelativeLayout
            android:id="@+id/rl"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:background="#262626">

            <TextView
                android:id="@+id/txtTitle"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:gravity="center"
                android:textColor="#FFF"
                android:textSize="26sp" />

        </RelativeLayout>

        <TextView
            android:id="@+id/txtDescription"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/rl"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="@dimen/activity_vertical_margin"
            android:layout_marginEnd="@dimen/activity_horizontal_margin"
            android:layout_marginStart="@dimen/activity_horizontal_margin"
            android:layout_marginTop="@dimen/activity_vertical_margin"
            android:textSize="18sp" />


        <Button
            android:id="@+id/button"
            android:background="#801f2124"
            android:text="TAP/SLIDE RIGHT TO VIEW TUTORIAL"
            android:textColor="#FFF"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true" />

    </RelativeLayout>

</android.support.v7.widget.CardView>

The code for the ChildFragment.java class is given below.

下面给出ChildFragment.java类的代码。

package com.journaldev.swipeviewpagerinshorts;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class ChildFragment extends Fragment {

    public ChildFragment() {
    }

    public static ChildFragment newInstance(DataModel dataModel, boolean isWebView) {
        ChildFragment fragment = new ChildFragment();
        Bundle args = new Bundle();
        args.putString("title", dataModel.title);
        args.putString("description", dataModel.description);
        args.putString("url", dataModel.url);
        args.putBoolean("isWebView", isWebView);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_child, container, false);
        RelativeLayout rl = rootView.findViewById(R.id.rl);
        WebView webView = rootView.findViewById(R.id.webView);
        TextView txtTitle = rootView.findViewById(R.id.txtTitle);
        Button button = rootView.findViewById(R.id.button);
        TextView txtDescription = rootView.findViewById(R.id.txtDescription);

        boolean isWebView = getArguments().getBoolean("isWebView");
        if (isWebView) {
            webView.setVisibility(View.VISIBLE);
            rl.setVisibility(View.GONE);
            button.setVisibility(View.GONE);
            txtDescription.setVisibility(View.GONE);

            webView.loadUrl(getArguments().getString("url"));

        } else {
            webView.setVisibility(View.GONE);
            rl.setVisibility(View.VISIBLE);
            txtDescription.setVisibility(View.VISIBLE);
            button.setVisibility(View.VISIBLE);

            txtTitle.setText(getArguments().getString("title"));
            txtDescription.setText(getArguments().getString("description"));
        }

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ParentFragment parentFrag = ((ParentFragment) ChildFragment.this.getParentFragment());
                parentFrag.nestedViewPager.setCurrentItem(1);
            }
        });


        return rootView;
    }
}

The isWebView parameter from newInstance method determines whether the WebView is shown/hidden. Button click would directly take the user to the WebView page.

newInstance方法中的isWebView参数确定是否显示/隐藏WebView 。 单击按钮将直接将用户带到WebView页面。

Changing ViewPager page dynamically.

动态更改ViewPager页面。

To change the ViewPager page we call the setCurrentItem() method on the ViewPager instance.

要更改ViewPager页面,我们在ViewPager实例上调用setCurrentItem()方法。

Don’t forget to add the CardView dependency to the build.gradle.

不要忘记将CardView依赖项添加到build.gradle

Android Vertical ViewPager应用程序输出 (Android Vertical ViewPager App Output)

The output of the above application in action.

android nested viewpager output

上面应用程序的输出生效。

向滑动效果添加动画 (Adding Animation to Swipe Effect)

Let’s animate the VerticalViewPager scrolling by creating a different PageTransformer class.

让我们通过创建一个不同的PageTransformer类来动画化VerticalViewPager滚动。

private class VerticalPageTransformerAnimate implements ViewPager.PageTransformer {
        private static final float MIN_SCALE = 0.75f;

        @Override
        public void transformPage(View view, float position) {

            int pageWidth = view.getWidth();
            int pageHeight = view.getHeight();
            float alpha = 0;
            if (0 <= position && position <= 1) {
                alpha = 1 - position;
            } else if (-1 < position && position < 0) {
                float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
                float verticalMargin = pageHeight * (1 - scaleFactor) / 2;
                float horizontalMargin = pageWidth * (1 - scaleFactor) / 2;
                if (position < 0) {
                    view.setTranslationX(horizontalMargin - verticalMargin / 2);
                } else {
                    view.setTranslationX(-horizontalMargin + verticalMargin / 2);
                }

                view.setScaleX(scaleFactor);
                view.setScaleY(scaleFactor);

                alpha = position + 1;
            }

            view.setAlpha(alpha);
            view.setTranslationX(view.getWidth() * -position);
            float yPosition = position * view.getHeight();
            view.setTranslationY(yPosition);

        }
    }

Initialise in the init method of the VerticalViewPager class in the following way.

通过以下方式在VerticalViewPager类的init方法中进行init

setPageTransformer(true, new VerticalPageTransformerAnimate());

The new output of the application is:

android vertical viewpager animation example output

该应用程序的新输出为:

This brings an end to android vertical ViewPager tutorial. Since the ViewPagers are swipeable in all four directions we’ve named the project as SwipeViewPagerInshorts. You can download it from the link below.

这就结束了android Vertical ViewPager教程。 由于ViewPagers可以在所有四个方向上滑动,因此我们将项目命名为SwipeViewPagerInshorts 。 您可以从下面的链接下载它。

翻译自: https://www.journaldev.com/19336/android-nested-viewpager-vertical-viewpager

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值