ViewPager+Fragment,Fragment里面嵌套Fragment的简单实现
程序员文章站
2022-06-08 13:06:54
...
今天整理ViewPager的一些内容,一方面巩固一下所学的Android知识,不能学了这忘了那;另一方面以后在需要的时候可以直接拿出来使用,不用再去重新去撸,可以节省点时间。内容还会持续更新加深。
需求
1.最外层是拨号、联系人、短信三个Fragment滑动
2.然后在拨号的Fragment里面嵌套了Fragment,分别是已拨电话,已接电话,未接电话3个Fragment
明确了目的就直接上代码
主Activity的布局viewpager_activity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="#333444"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_dial"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="拨号"
android:textColor="#ffffff"
android:textSize="18sp"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_contacts"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="联系人"
android:textColor="#ffffff"
android:textSize="18sp"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_sms"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="短信"
android:textColor="#ffffff"
android:textSize="18sp"
tools:ignore="HardcodedText" />
</LinearLayout>
<android.support.v4.view.ViewPager
android:id="@+id/vp_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
然后是拨号、联系人、短信3个人Fragment的布局,
fragment_dial.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="36dp"
android:orientation="horizontal"
tools:ignore="UselessParent">
<TextView
android:id="@+id/tv_yibodianhua"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="已拨电话"
android:textColor="#4a4a4a"
android:textSize="16sp"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_yijiedianhua"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="已接电话"
android:textColor="#4a4a4a"
android:textSize="16sp"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_weijiedianhua"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="未接电话"
android:textColor="#4a4a4a"
android:textSize="16sp"
tools:ignore="HardcodedText" />
</LinearLayout>
<android.support.v4.view.ViewPager
android:id="@+id/vp_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
后面两个布局简单也都是一样的,这里就不多啰嗦了
接着就是主Activity的实现
/**
* 实现标题控件的监听接口,viewpager的页面改变监听接口
*/
public class VpActivity extends FragmentActivity implements ViewPager.OnPageChangeListener, View.OnClickListener {
private ViewPager mViewPager;
private TextView mTvDial, mTvContacts, mTvSMS;
//定义一个list来存放Fragment,建议这里的Fragment使用v4包下面的
private List<Fragment> mFragmentLists;
//自定义一个适配器
private ViewPagerAdapter mAdater;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewpager_activity);
initView();
initEvent();
mAdater = new ViewPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mAdater);
}
//初始化控件
private void initView() {
mViewPager = findViewById(R.id.vp_viewpager);
mTvDial = findViewById(R.id.tv_dial);
mTvContacts = findViewById(R.id.tv_contacts);
mTvSMS = findViewById(R.id.tv_sms);
mFragmentLists = new ArrayList<>();
mFragmentLists.add(new DialFragment());
mFragmentLists.add(new ContactsFragment());
mFragmentLists.add(new SMSFragment());
//默认进入应用第一个被选中
resetTextViewColor();
mTvDial.setTextColor(Color.parseColor("#1FB79F"));
}
//设置监听
private void initEvent() {
mViewPager.addOnPageChangeListener(this);
mTvDial.setOnClickListener(this);
mTvContacts.setOnClickListener(this);
mTvSMS.setOnClickListener(this);
}
/**
* 官方注释:
* Callback interface for responding to changing state of the selected page.
* <p>
* 页面被选择回调(这翻译确实有点生硬,硬伤啊)
*/
@Override
public void onPageSelected(int position) {
resetTextViewColor();
switch (position) {
case 0:
mTvDial.setTextColor(Color.parseColor("#1FB79F"));
break;
case 1:
mTvContacts.setTextColor(Color.parseColor("#1FB79F"));
break;
case 2:
mTvSMS.setTextColor(Color.parseColor("#1FB79F"));
break;
}
}
//页面滑动过程中回调
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
//页面滑动状态监听
@Override
public void onPageScrollStateChanged(int state) {
}
//点击事件,当点击标题的时候,通过传入当前点击的页面的position,调用mViewPager.setCurrentItem()来实现页面的变化
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.tv_dial:
mViewPager.setCurrentItem(0);
break;
case R.id.tv_contacts:
mViewPager.setCurrentItem(1);
break;
case R.id.tv_sms:
mViewPager.setCurrentItem(2);
break;
}
}
//颜色初始化
private void resetTextViewColor() {
mTvDial.setTextColor(Color.WHITE);
mTvContacts.setTextColor(Color.WHITE);
mTvSMS.setTextColor(Color.WHITE);
}
//适配器
class ViewPagerAdapter extends FragmentPagerAdapter {
ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
//获取Fragment
@Override
public Fragment getItem(int position) {
return mFragmentLists.get(position);
}
//总共有mFragmentLists.size()个需要显示
@Override
public int getCount() {
return mFragmentLists.size();
}
}
}
通过以上代码就可以实现第一个需求(外层的滑动)
最后上嵌套Fragment的代码
public class DialFragment extends Fragment implements View.OnClickListener, ViewPager.OnPageChangeListener {
private ViewPager mViewPager;
private TextView mTv1, mTv2, mTv3;
private List<Fragment> fragmentList;
private VpAdapter mAdapter;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_dial, container, false);
initView(view);
return view;
}
private void initView(View view) {
mViewPager = view.findViewById(R.id.vp_fragment);
mTv1 = view.findViewById(R.id.tv_yibodianhua);
mTv2 = view.findViewById(R.id.tv_yijiedianhua);
mTv3 = view.findViewById(R.id.tv_weijiedianhua);
mViewPager.addOnPageChangeListener(this);
mTv1.setOnClickListener(this);
mTv2.setOnClickListener(this);
mTv3.setOnClickListener(this);
fragmentList = new ArrayList<>();
fragmentList.add(new YBTel());
fragmentList.add(new YJTel());
fragmentList.add(new WJTel());
mAdapter = new VpAdapter(getChildFragmentManager());
mViewPager.setAdapter(mAdapter);
resetTextViewColor();
mTv1.setTextColor(Color.parseColor("#1FB79F"));
}
@Override
public void onPageSelected(int position) {
resetTextViewColor();
switch (position) {
case 0:
mTv1.setTextColor(Color.parseColor("#1FB79F"));
break;
case 1:
mTv2.setTextColor(Color.parseColor("#1FB79F"));
break;
case 2:
mTv3.setTextColor(Color.parseColor("#1FB79F"));
break;
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.tv_yibodianhua:
mViewPager.setCurrentItem(0);
break;
case R.id.tv_yijiedianhua:
mViewPager.setCurrentItem(1);
break;
case R.id.tv_weijiedianhua:
mViewPager.setCurrentItem(2);
break;
}
}
private void resetTextViewColor() {
mTv1.setTextColor(Color.parseColor("#4a4a4a"));
mTv2.setTextColor(Color.parseColor("#4a4a4a"));
mTv3.setTextColor(Color.parseColor("#4a4a4a"));
}
class VpAdapter extends FragmentPagerAdapter {
VpAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public int getCount() {
return fragmentList.size();
}
}
}
这里面的逻辑与上面外层的逻辑相似,可以参考上面的去理解
需要注意的是:mAdapter = new VpAdapter(getChildFragmentManager())这句
getChildFragmentManager()获取Fragment内部子容器的管理器
好了,这样就实现了上面提出的两个需求,此博文持续加入新东西,如有错误之处,请多多指教!