文章目錄
1. 簡介
常常羨慕於別人分享的自定義ViewPager聯動效果。近期項目中用到聯動效果,找來一個不錯的框架用到了項目中。發現有幾個問題:一是難以適應自己項目的設計風格;二是適應自己項目的交互比較麻煩;三是不知所以然導致維護和修改困難。於是決定自己實現,同時掀一掀它的內幕。
下圖是我們的實現目標:
2. 要點
2.1 角標如何佈局
因爲需要在每一個導航的 tab 右上角加上角標。所以需要寫好角標的佈局。因爲需要讓角標始終在文字的右上角,於是我就想到了 RelativeLayout 相對佈局,它可以設置角標的相對位置,非常適合現在這個場景(當然 ConstraintLauout 也可以)。佈局代碼如下示例:
layout/layout_tab_cell_num.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rl_tab_cell"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="2dp"
android:paddingRight="2dp">
<TextView
android:id="@+id/tv_tab_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="報送"
android:textColor="#ffffff"
android:textSize="16dp"
android:alpha="0.6"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
/>
<TextView
android:id="@+id/tv_msg_num"
android:layout_width="wrap_content"
android:layout_height="16dp"
android:minWidth="16dp"
android:background="@drawable/shape_tab_msg_bg_red"
android:layout_gravity="center"
android:visibility="gone"
tools:visibility="visible"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:paddingBottom="0.5dp"
android:gravity="center"
android:lines="1"
android:maxLines="1"
android:textStyle="bold"
android:text="99"
android:textSize="10dp"
android:textColor="@color/color_white"
android:layout_toRightOf="@id/tv_tab_name"
android:layout_above="@id/tv_tab_name"
android:layout_marginLeft="-14dp"
android:layout_marginBottom="-12dp"
/>
<TextView
android:id="@+id/tv_red_dot"
android:layout_width="8dp"
android:layout_height="8dp"
android:background="@drawable/shape_tab_msg_bg_red"
android:layout_gravity="center"
android:visibility="gone"
tools:visibility="gone"
android:layout_toRightOf="@id/tv_tab_name"
android:layout_above="@id/tv_tab_name"
android:layout_marginLeft="-12dp"
android:layout_marginBottom="-8dp"
/>
</RelativeLayout>
上面佈局代碼中,通過
android:layout_toRightOf="@id/tv_tab_name"
android:layout_above="@id/tv_tab_name"
控制角標數字或角標紅點的位置,通過
android:layout_marginLeft="-12dp"
android:layout_marginBottom="-8dp"
控制角標向 tab 文字內部縮進(相對於文字向左向下縮進)。
drawable/shape_tab_msg_bg_red.xml
的佈局如下,common:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 內部顏色 -->
<solid android:color="@color/color_red" />
<!-- 邊緣線條顏色 -->
<stroke
android:width="1dp"
android:color="@color/common_color" />
<!-- 圓角的幅度 -->
<corners android:radius="100dp" />
</shape>
注意: 邊緣線條顏色 最好 與背景色一致 。
2.2 如何與Indicator實現聯動
Tab 切換需要一個指示器,用於明確指示我們處在那個頁面,我們需要讓 ViewPager 的頁面和 Tab樣式和指示器一一對應。
我們可以使用動畫,但是有麻煩,如果在頁面切換時使用動畫去實現,我們很難保證指示器的動畫能與 ViewPager 的頁面切換節奏保持一致。節奏不一致,就會不流暢。
怎麼辦呢?我注意到 ViewPager 可以添加一個監聽:addOnPageChangeListener(OnPageChangeListener)
。
onPageChangeListener 的源碼如下:
/**
* Callback interface for responding to changing state of the selected page.
*/
public interface OnPageChangeListener {
/**
* This method will be invoked when the current page is scrolled, either as part
* of a programmatically initiated smooth scroll or a user initiated touch scroll.
*
* @param position Position index of the first page currently being displayed.
* Page position+1 will be visible if positionOffset is nonzero.
* @param positionOffset Value from [0, 1) indicating the offset from the page at position.
* @param positionOffsetPixels Value in pixels indicating the offset from position.
*/
void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);
/**
* This method will be invoked when a new page becomes selected. Animation is not
* necessarily complete.
*
* @param position Position index of the new selected page.
*/
void onPageSelected(int position);
/**
* Called when the scroll state changes. Useful for discovering when the user
* begins dragging, when the pager is automatically settling to the current page,
* or when it is fully stopped/idle.
*
* @param state The new scroll state.
* @see ViewPager#SCROLL_STATE_IDLE
* @see ViewPager#SCROLL_STATE_DRAGGING
* @see ViewPager#SCROLL_STATE_SETTLING
*/
void onPageScrollStateChanged(int state);
}
onPageSelected
和 onPageScrollStateChanged
我們應該很熟悉了,
onPageSelected
在新頁面被選擇示會被調用,動畫未必完成;
onPageScrollStateChanged
在當滾動狀態改版時調用,有三種狀態。
還有一個方法比較少用到:
onPageScrolled
在當前頁面被滾動時調用,有三個參數:
position
翻譯:當前正在顯示的第一頁的位置索引。如果 positionOffset 不爲 0,position+1 頁會顯示。
事實上:當頁面正在滾動時,即滾動未完成,postion 表示 左邊頁面的下標,無論是左滑還是右滑,postion+1 即是右邊頁面的下標。positionOffset
從[0, 1)的值,表示頁面的偏移量。positionOffsetPixels
偏移量的 pixel 值。
通過 onPageScrolled
方法的 position 和 positionOffset
我們可以算出 指示器(Indicator View)
的位置。如下所示:
圖爲指示器中心點位置計算:
int dist = (leftCell.getWidth() + rightCell.getWidth()) / 2;
float indicatorCenterX = leftCell.getLeft() + leftCell.getWidth() / 2 + dist * positionOffset;
int translationX = (int) (indicatorCenterX - mIndicatorView.getWidth() / 2);
mIndicatorView.setTranslationX(translationX);
positionOffset 是隨着頁面的切換而不斷變化的,因此可以,通過setTranslationX 設置 indicatorView 的位移量 translationX 來控制 indicatorView 的移動。
3. 實現
3.1 佈局
導航欄 tab 的佈局上面已經給出,下面是導航、指示器、ViewPager的佈局:
layout/activity_nav.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".nav.NavActivity">
<HorizontalScrollView
android:id="@+id/hsv_nav_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/common_color"
android:scrollbars="none">
<FrameLayout
android:id="@+id/fl_nav_frame"
android:layout_width="wrap_content"
android:layout_height="44dp">
<LinearLayout
android:id="@+id/ll_tab_group"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
</LinearLayout>
<View
android:id="@+id/indicator_view"
android:layout_width="18dp"
android:layout_height="2dp"
android:background="@color/color_white"
android:layout_gravity="bottom"
android:layout_marginBottom="4dp"/>
</FrameLayout>
</HorizontalScrollView>
<android.support.v4.view.ViewPager
android:id="@+id/vp_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
佈局很簡單,如果tab數量固定且有限,不需要水平滾動條,可以把水平滾動條去掉,在@+id/ll_tab_group
中,根據上面角標佈局,寫自己的 tab 組合。
3.2 導航欄
第一步:準備數據
private void initData() {
mFuncEntityList.add(new FuncEntity("關注", 0));
mFuncEntityList.add(new FuncEntity("推薦", 1));
mFuncEntityList.add(new FuncEntity("視頻", 2));
mFuncEntityList.add(new FuncEntity("熱點", 3));
mFuncEntityList.add(new FuncEntity("直播", 4));
mFuncEntityList.add(new FuncEntity("精品課", 5));
mFuncEntityList.add(new FuncEntity("娛樂", 6));
mFuncEntityList.add(new FuncEntity("科技", 7));
mFuncEntityList.add(new FuncEntity("懂車帝", 8));
mFuncEntityList.add(new FuncEntity("財經", 9));
mFuncEntityList.add(new FuncEntity("國際", 10));
mFuncEntityList.add(new FuncEntity("體育", 11));
mFuncEntityList.add(new FuncEntity("問答", 12));
}
數據類如下
import java.io.Serializable;
public class FuncEntity implements Serializable {
/**
* funName : 關注
* id : 2
*/
private String funName;
private int id;
public FuncEntity() {
}
public FuncEntity(String funName, int id) {
this.funName = funName;
this.id = id;
}
public String getFunName() {
return funName;
}
public void setFunName(String funName) {
this.funName = funName;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
第二步:初始化導航欄,爲 ViewPager 設置適配器
@Override
public void initView() {
mFragmentManager = getSupportFragmentManager();
//find views
mHsvNavBar = (HorizontalScrollView) findViewById(R.id.hsv_nav_bar);
mFlNavFrame = (FrameLayout) findViewById(R.id.fl_nav_frame);
mLlTabGroup = (LinearLayout) findViewById(R.id.ll_tab_group);
mIndicatorView = findViewById(R.id.indicator_view);
mVpContent = (ViewPager) findViewById(R.id.vp_content);
//初始化導航欄
for (int i = 0; i < mFuncEntityList.size(); i++) {
FuncEntity funcEntity = mFuncEntityList.get(i);
RelativeLayout rlTabCell = (RelativeLayout) getLayoutInflater().inflate(R.layout.layout_tab_cell_num, mLlTabGroup, false);
TextView tvTabName = (TextView) rlTabCell.findViewById(R.id.tv_tab_name);
TextView tvMsgNum = (TextView) rlTabCell.findViewById(R.id.tv_msg_num);
TextView tvRedDot = (TextView) rlTabCell.findViewById(R.id.tv_red_dot);
tvMsgNum.setVisibility(View.GONE);
tvRedDot.setVisibility(View.GONE);
tvTabName.setText(funcEntity.getFunName());
rlTabCell.setTag(funcEntity.getId());
mLlTabGroup.addView(rlTabCell);
}
mPagerAdapter = new FragmentPagerAdapter(mFragmentManager) {
@Override
public Fragment getItem(int position) {
return getFuncFragment(mFuncEntityList.get(position));
}
@Override
public int getCount() {
return mFuncEntityList.size();
}
};
mVpContent.setAdapter(mPagerAdapter);
//請求角標數量
for (FuncEntity funcEntity : mFuncEntityList) {
requestMsgNum(funcEntity);
}
}
/**
* Map集合,關聯FuncEntity和Fragment,保存二者鍵值對,使二者具有一一對應關係。
*/
private Map<FuncEntity, BaseFuncFragment> mFuncFragmentMap = new HashMap<>();
private BaseFuncFragment getFuncFragment(FuncEntity funcEntity) {
BaseFuncFragment funcFragment = mFuncFragmentMap.get(funcEntity);
if (funcFragment == null) {
funcFragment = CommFuncFragment.newInstance(funcEntity);
if (funcFragment != null) {
mFuncFragmentMap.put(funcEntity, funcFragment);
}
}
return funcFragment;
}
Random random = new Random();
private int getMsgNum() {
int num = random.nextInt(99) + 1;
// Log.i("NavActivity", "getMsgNum: " + num);
return num;
}
/**
* 請求角標數量
*/
private void requestMsgNum(FuncEntity funcEntity) {
//請求角標數量
//......
//更新角標
updateTabNum(funcEntity.getId(), getMsgNum());
}
/**
* 更新數字
*
* @param tabId
* @param tabNum
*/
public void updateTabNum(int tabId, int tabNum) {
View tabView = mLlTabGroup.findViewWithTag(tabId);
if (tabView != null) {
TextView tvMsgNum = tabView.findViewById(R.id.tv_msg_num);
String tabNumStr = tabNum > 99 ? String.valueOf(99).concat("+") : String.valueOf(tabNum);
tvMsgNum.setText(tabNumStr);
tvMsgNum.setVisibility(tabNum == 0 ? View.GONE:View.VISIBLE);
}
}
/**
* 清除角標
* @param tabId
*/
public void clearTabNum(int tabId) {
updateTabNum(tabId, 0);
}
3.3 導航欄與ViewPager聯動
需要爲每一個 tab 設置點擊監聽:
for (int i = 0; i < mLlTabGroup.getChildCount(); i++) {
final int pos = i;
mLlTabGroup.getChildAt(i).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mVpContent.setCurrentItem(pos);
}
});
}
3.4 tab切換效果
mVpContent.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
private int lastPost = 0;
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
if (Math.abs(position - lastPost) > 0) {
int llPos = lastPost;
int lrPos = lastPost == mFuncEntityList.size() - 1 ? lastPost : lastPost + 1;
int clPos = position;
int crPos = position == mFuncEntityList.size() - 1 ? position : position + 1;
if (llPos != clPos && llPos != crPos) {
mLlTabGroup.getChildAt(llPos).findViewById(R.id.tv_tab_name).setAlpha(0.6f);
}
if (lrPos != clPos && lrPos != crPos) {
mLlTabGroup.getChildAt(lrPos).findViewById(R.id.tv_tab_name).setAlpha(0.6f);
}
}
//設置指示器位移
RelativeLayout leftCell = (RelativeLayout) mLlTabGroup.getChildAt(position);
int rightPos = position == mFuncEntityList.size() - 1 ? position : position + 1;
RelativeLayout rightCell = (RelativeLayout) mLlTabGroup.getChildAt(rightPos);
float dist = (leftCell.getWidth() + rightCell.getWidth()) / 2f;
float indicatorCenterX = leftCell.getLeft() + leftCell.getWidth() / 2f + dist * positionOffset;
int translationX = (int) (indicatorCenterX - mIndicatorView.getWidth() / 2f);
mIndicatorView.setTranslationX(translationX);
//水平滾動條自動滾動
mHsvNavBar.scrollTo((int) (indicatorCenterX - mHsvNavBar.getWidth() / 2f), 0);
//文字透明度
if (position != rightPos) {
rightCell.findViewById(R.id.tv_tab_name).setAlpha(0.6f + 0.4f * positionOffset);
leftCell.findViewById(R.id.tv_tab_name).setAlpha(1f - 0.4f * positionOffset);
} else {
leftCell.findViewById(R.id.tv_tab_name).setAlpha(1f - 0.4f * positionOffset);
}
lastPost = position;
}
});
4. 代碼
完整代碼:
NavActivity.java
import android.os.Bundle;
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.view.View;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.wzhy.viewpagerserial.base.BaseActivity;
import com.wzhy.viewpagerserial.R;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class NavActivity extends BaseActivity {
private HorizontalScrollView mHsvNavBar;
private FrameLayout mFlNavFrame;
private LinearLayout mLlTabGroup;
private View mIndicatorView;
private ViewPager mVpContent;
private ArrayList<FuncEntity> mFuncEntityList = new ArrayList<>();
private FuncEntity mCurrFuncEntity;
private FragmentManager mFragmentManager;
private FragmentPagerAdapter mPagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nav);
initData();
initView();
setListeners();
//請求角標數量
for (FuncEntity funcEntity : mFuncEntityList) {
requestMsgNum(funcEntity);
}
}
private void initData() {
mFuncEntityList.add(new FuncEntity("關注", 0));
mFuncEntityList.add(new FuncEntity("推薦", 1));
mFuncEntityList.add(new FuncEntity("視頻", 2));
mFuncEntityList.add(new FuncEntity("熱點", 3));
mFuncEntityList.add(new FuncEntity("直播", 4));
mFuncEntityList.add(new FuncEntity("精品課", 5));
mFuncEntityList.add(new FuncEntity("娛樂", 6));
mFuncEntityList.add(new FuncEntity("科技", 7));
mFuncEntityList.add(new FuncEntity("懂車帝", 8));
mFuncEntityList.add(new FuncEntity("財經", 9));
mFuncEntityList.add(new FuncEntity("國際", 10));
mFuncEntityList.add(new FuncEntity("體育", 11));
mFuncEntityList.add(new FuncEntity("問答", 12));
mCurrFuncEntity = mFuncEntityList.get(0);
}
@Override
public void initView() {
mFragmentManager = getSupportFragmentManager();
//find views
mHsvNavBar = (HorizontalScrollView) findViewById(R.id.hsv_nav_bar);
mFlNavFrame = (FrameLayout) findViewById(R.id.fl_nav_frame);
mLlTabGroup = (LinearLayout) findViewById(R.id.ll_tab_group);
mIndicatorView = findViewById(R.id.indicator_view);
mVpContent = (ViewPager) findViewById(R.id.vp_content);
//初始化導航欄
for (int i = 0; i < mFuncEntityList.size(); i++) {
FuncEntity funcEntity = mFuncEntityList.get(i);
RelativeLayout rlTabCell = (RelativeLayout) getLayoutInflater().inflate(R.layout.layout_tab_cell_num, mLlTabGroup, false);
TextView tvTabName = (TextView) rlTabCell.findViewById(R.id.tv_tab_name);
TextView tvMsgNum = (TextView) rlTabCell.findViewById(R.id.tv_msg_num);
TextView tvRedDot = (TextView) rlTabCell.findViewById(R.id.tv_red_dot);
tvMsgNum.setVisibility(View.GONE);
tvRedDot.setVisibility(View.GONE);
tvTabName.setText(funcEntity.getFunName());
rlTabCell.setTag(funcEntity.getId());
mLlTabGroup.addView(rlTabCell);
}
mPagerAdapter = new FragmentPagerAdapter(mFragmentManager) {
@Override
public Fragment getItem(int position) {
return getFuncFragment(mFuncEntityList.get(position));
}
@Override
public int getCount() {
return mFuncEntityList.size();
}
};
mVpContent.setAdapter(mPagerAdapter);
}
/**
* Map集合,關聯FuncEntity和Fragment,保存二者鍵值對,使二者具有一一對應關係。
*/
private Map<FuncEntity, BaseFuncFragment> mFuncFragmentMap = new HashMap<>();
private BaseFuncFragment getFuncFragment(FuncEntity funcEntity) {
BaseFuncFragment funcFragment = mFuncFragmentMap.get(funcEntity);
if (funcFragment == null) {
funcFragment = CommFuncFragment.newInstance(funcEntity);
if (funcFragment != null) {
mFuncFragmentMap.put(funcEntity, funcFragment);
}
}
return funcFragment;
}
Random random = new Random();
private int getMsgNum() {
int num = random.nextInt(99) + 1;
// Log.i("NavActivity", "getMsgNum: " + num);
return num;
}
/**
* 請求角標數量
*/
private void requestMsgNum(FuncEntity funcEntity) {
//請求角標數量
//......
//更新角標
updateTabNum(funcEntity.getId(), getMsgNum());
}
/**
* 更新數字
*
* @param tabId
* @param tabNum
*/
public void updateTabNum(int tabId, int tabNum) {
View tabView = mLlTabGroup.findViewWithTag(tabId);
if (tabView != null) {
TextView tvMsgNum = tabView.findViewById(R.id.tv_msg_num);
String tabNumStr = tabNum > 99 ? String.valueOf(99).concat("+") : String.valueOf(tabNum);
tvMsgNum.setText(tabNumStr);
tvMsgNum.setVisibility(tabNum == 0 ? View.GONE : View.VISIBLE);
}
}
/**
* 清除角標
*
* @param tabId
*/
public void clearTabNum(int tabId) {
updateTabNum(tabId, 0);
}
@Override
public void setListeners() {
for (int i = 0; i < mLlTabGroup.getChildCount(); i++) {
final int pos = i;
mLlTabGroup.getChildAt(i).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mVpContent.setCurrentItem(pos);
}
});
}
mVpContent.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
private int lastPost = 0;
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
if (Math.abs(position - lastPost) > 0) {
int llPos = lastPost;
int lrPos = lastPost == mFuncEntityList.size() - 1 ? lastPost : lastPost + 1;
int clPos = position;
int crPos = position == mFuncEntityList.size() - 1 ? position : position + 1;
if (llPos != clPos && llPos != crPos) {
mLlTabGroup.getChildAt(llPos).findViewById(R.id.tv_tab_name).setAlpha(0.6f);
}
if (lrPos != clPos && lrPos != crPos) {
mLlTabGroup.getChildAt(lrPos).findViewById(R.id.tv_tab_name).setAlpha(0.6f);
}
}
//設置指示器位移
RelativeLayout leftCell = (RelativeLayout) mLlTabGroup.getChildAt(position);
int rightPos = position == mFuncEntityList.size() - 1 ? position : position + 1;
RelativeLayout rightCell = (RelativeLayout) mLlTabGroup.getChildAt(rightPos);
float dist = (leftCell.getWidth() + rightCell.getWidth()) / 2f;
float indicatorCenterX = leftCell.getLeft() + leftCell.getWidth() / 2f + dist * positionOffset;
int translationX = (int) (indicatorCenterX - mIndicatorView.getWidth() / 2f);
mIndicatorView.setTranslationX(translationX);
//水平滾動條自動滾動
mHsvNavBar.scrollTo((int) (indicatorCenterX - mHsvNavBar.getWidth() / 2f), 0);
//文字透明度
if (position != rightPos) {
rightCell.findViewById(R.id.tv_tab_name).setAlpha(0.6f + 0.4f * positionOffset);
leftCell.findViewById(R.id.tv_tab_name).setAlpha(1f - 0.4f * positionOffset);
} else {
leftCell.findViewById(R.id.tv_tab_name).setAlpha(1f - 0.4f * positionOffset);
}
lastPost = position;
}
});
}
private FuncEntity getCurrFuncEntity() {
return mFuncEntityList.get(mVpContent.getCurrentItem());
}
@Override
public void onClick(View v) {
}
}
NavActivity.java
import android.support.v7.app.AppCompatActivity;
import android.view.View;
public abstract class BaseActivity extends AppCompatActivity implements IView {
protected View.OnClickListener mOnClickListener;
protected View.OnClickListener getOnClickListener() {
if (mOnClickListener == null) {
mOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
BaseActivity.this.onClick(v);
}
};
}
return mOnClickListener;
}
}
IView.java
import android.view.View;
public interface IView {
void initView();
void setListeners();
void onClick(View v);
}
BaseFuncFragment.java
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import com.wzhy.viewpagerserial.base.IView;
public abstract class BaseFuncFragment extends Fragment implements IView {
protected FuncEntity mFuncEntity;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
if (args.containsKey("funcEntity")) {
mFuncEntity = (FuncEntity) args.getSerializable("funcEntity");
}
}
}
CommFuncFragment.java
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.wzhy.viewpagerserial.R;
/**
*
*/
public class CommFuncFragment extends BaseFuncFragment {
private View mView;
public CommFuncFragment() {
}
public static CommFuncFragment newInstance(FuncEntity funcEntity) {
Bundle args = new Bundle();
args.putSerializable("funcEntity", funcEntity);
CommFuncFragment fragment = new CommFuncFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.fragment_comm_func, container, false);
initView();
return mView;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setListeners();
}
@Override
public void initView() {
((TextView) mView.findViewById(R.id.tv_page_name)).setText(mFuncEntity.getFunName());
}
@Override
public void setListeners() {
}
@Override
public void onClick(View v) {
}
}
fragment_comm_func.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".nav.CommFuncFragment">
<TextView
android:id="@+id/tv_page_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="48dp"
tools:text="tabName"
android:textColor="@color/common_color"
android:layout_gravity="center"/>
</FrameLayout>
5. 參考
項目地址:
github:https://github.com/wangzhengyangNo1/ViewPagerSerialDemo