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。 我们将开发一个应用程序,该应用程序可以复制Inshorts和Flipboard等应用程序中存在的滑动功能。
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 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 theVerticalViewPager
. Invokes theParentViewPagerAdapter
that creates instances ofParentFragment
MainActivity
–包含父ViewPager,即VerticalViewPager
。 调用ParentViewPagerAdapter
创建的实例ParentFragment
VerticalViewPager
– Contains a custom implementation of ViewPager that scrolls vertically. The pages hold aParentFragment
view which is supplied byParentViewPagerAdapter
.VerticalViewPager
–包含ViewPager的自定义实现,该实现可垂直滚动。 这些页面包含由ParentViewPagerAdapter
提供的ParentFragment
视图。ParentFragment
– It’s present inside theVerticalViewPager
. It holds another ViewPager and it’s adapter code is in the fileChildViewPagerAdapter
. Fragment’s layout is defined infragment_parent.xml
.ParentFragment
–它存在于VerticalViewPager
。 它包含另一个ViewPager,其适配器代码在文件ChildViewPagerAdapter
。 Fragment的布局在fragment_parent.xml
定义。ChildViewPagerAdapter
– Contains the implementation of nested ViewPager. It holds and suppliesChildFragment
‘s to theParentFragment
.ChildViewPagerAdapter
–包含嵌套ViewPager的实现。 它持有并提供ChildFragment
到ParentFragment
。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 theChildFragment
.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 theParentFragment
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:
注意 :为了避免在类中使用长字符串,我们在项目的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 methodtrigger
. The trigger method passes the relevant page index to theMainActivity
. Read communicating data from fragmentsinterface 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.
上面应用程序的输出生效。
向滑动效果添加动画 (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:
该应用程序的新输出为:
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