记录一下最近项目中有一个类似于京东客户端选择收货地址的需求。
本次实现主要用到ViewPager、Fragment、TabLayout 主要代码:TabActivity.java
public class TabActivity extends AppCompatActivity {
private ViewPager mViewPager;
private TabLayout mTab;
private List mFragments;
private List mTitles;
private FragmentPagerAdapter mAdapter;
private CustomBroadcast mReceiver;
private String mRecordBuildingName = null;
private String mRecordUnitName = null;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tablayout);
mReceiver = new CustomBroadcast();
IntentFilter filter = new IntentFilter();
filter.addAction("lpf1");
filter.addAction("lpf2");
filter.addAction("lpf3");
registerReceiver(mReceiver, filter);
mTitles = new ArrayList<>();
mFragments = new ArrayList<>();
mTab = findViewById(R.id.tablayout);
mViewPager = findViewById(R.id.vp_viewpager);
initViewPager();
initTabData();
}
private void initViewPager() {
mTitles.add("请选择");
mFragments.add(0, new FirstFragment());
mAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return mFragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
return mTitles.get(position);
}
};
mViewPager.setAdapter(mAdapter);
/*
* 将TabLayout、ViewPager 的监听事件同步
* 对TabLayout 的适配器进行重置
* 对TabLayout 的 TabItem 进行重置
* 从ViewPager 的 Adapter 中读取到每一页的标题,并为之创建 TabItem 添加到 TabLayout 中
*/
mTab.setupWithViewPager(mViewPager);
}
private void initTabData() {
mTab.setSelectedTabIndicatorColor(getResources().getColor(R.color.colorAccent));
mTab.setTabTextColors(getResources().getColor(R.color.white),
getResources().getColor(R.color.colorAccent));
mTab.setTabMode(TabLayout.MODE_SCROLLABLE);
mTab.setBackgroundResource(R.color.colorPrimaryDarkNew);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
}
class CustomBroadcast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
mTitles.clear();
mFragments.clear();
mFragments.add(0, new FirstFragment());
mFragments.add(1, new SecondFragment());
if (Objects.equals(intent.getAction(), "lpf1")) {
String buildingName = intent.getStringExtra("FirstFragment");
mRecordBuildingName = buildingName;
if (buildingName != null) {
mTitles.add(0, buildingName);
mTitles.add(1, "请选择");
mAdapter.notifyDataSetChanged();
mViewPager.setCurrentItem(1);
}
} else if (Objects.equals(intent.getAction(), "lpf2")) {
String unitName = intent.getStringExtra("SecondFragment");
mRecordUnitName = unitName;
Log.e("spspsp", "单元名称:" + unitName);
if (unitName != null) {
mTitles.add(0, mRecordBuildingName);
mTitles.add(1, unitName);
mTitles.add(2, "请选择");
mFragments.add(2, new ThirdFragment());
mAdapter.notifyDataSetChanged();
mViewPager.setCurrentItem(2);
}
} else if (Objects.equals(intent.getAction(), "lpf3")) {
String roomName = intent.getStringExtra("ThirdFragment");
Log.e("spspsp", "房屋名称:" + roomName);
if (roomName != null) {
mTitles.add(0, mRecordBuildingName);
mTitles.add(1, mRecordUnitName);
mTitles.add(2, roomName);
mFragments.add(2, new ThirdFragment());
mAdapter.notifyDataSetChanged();
}
}
}
}
}
注意:这里当时在重写ViewPager适配器的时候,上面的Tab标签字样不能正常显示,
原因在于 mTab.setupWithViewPager(mViewPager),点进去看源码发现如下:
void populateFromPagerAdapter() {
removeAllTabs();
if (mPagerAdapter != null) {
final int adapterCount = mPagerAdapter.getCount();
for (int i = 0; i < adapterCount; i++) {
addTab(newTab().setText(mPagerAdapter.getPageTitle(i)), false);
}
// Make sure we reflect the currently set ViewPager item
if (mViewPager != null && adapterCount > 0) {
final int curItem = mViewPager.getCurrentItem();
if (curItem != getSelectedTabPosition() && curItem < getTabCount()) {
selectTab(getTabAt(curItem));
}
}
}
}
可以发现进入到if语句内的第一个for循环就是在为Tab标签赋值,具体值是通过ViewPager的getPageTitle方法,那么继续看getPageTitle方法,如下:
/**
* This method may be called by the ViewPager to obtain a title string
* to describe the specified page. This method may return null
* indicating no title for this page. The default implementation returns
* null.
*
* @param position The position of the title requested
* @return A title for the requested page
*/
@Nullable
public CharSequence getPageTitle(int position) {
return null;
}
可以看到在默认情况下,该方法的默认值都是null,这样就解释了Tab标签不能正常显示的原因了。