# FragmentViewPagerTabLayout
**Repository Path**: HackerX9/FragmentViewPagerTabLayout
## Basic Information
- **Project Name**: FragmentViewPagerTabLayout
- **Description**: TabLayout Fragment ViewPager
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2017-11-07
- **Last Updated**: 2020-12-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Fragment ViewPager TabLayout
## Fragment生命周期
1. 在xml中绑定Fragment:fragment节点:里面需要有id或者tag;可以通过android:name或者class来关联一个Fragment类.
```
```
当Fragment为V4包时,先执行Fragment的onStart()方法再执行Activity的
**启动MainActivity
**
``MainActivity: ---onCreate()--->first``
``FirstFragment: ---FirstFragment()--->``
``FirstFragment: ---onAttach()--->activity``
``FirstFragment: ---onAttach()--->context``
``FirstFragment: ---onCreate()--->``
``FirstFragment: ---onCreateView()--->``
``FirstFragment: ---onViewCreated()--->``
``MainActivity: ---onCreate()--->second``
FirstFragment: ---onActivityCreated()--->
MainActivity: ---onStart()--->
FirstFragment: ---onStart()--->
MainActivity: ---onResume()--->
FirstFragment: ---onResume()--->
**启动SecondActivity
**
FirstFragment: ---onPause()--->
MainActivity: ---onPause()--->
SecondActivity: ---onCreate()--->First
SecondFragment: ---SecondFragment()--->
SecondFragment: ---onAttach()--->activity
SecondFragment: ---onAttach()--->context
SecondFragment: ---onCreate()--->
SecondFragment: ---onViewCreated()--->
SecondActivity: ---onCreate()--->Second
SecondFragment: ---onActivityCreated()--->
SecondActivity: ---onStart()--->
SecondFragment: ---onStart()--->
SecondActivity: ---onResume()--->
SecondFragment: ---onResume()--->
FirstFragment: ---onStop()--->
MainActivity: ---onStop()--->
**结束SecondActivity
**
SecondFragment: ---onPause()--->
SecondActivity: ---onPause()--->
MainActivity: ---onRestart()--->
MainActivity: ---onStart()--->
FirstFragment: ---onStart()--->
MainActivity: ---onResume()--->
FirstFragment: ---onResume()--->
SecondFragment: ---onStop()--->
SecondActivity: ---onStop()--->
SecondFragment: ---onDestroyView()--->
SecondFragment: ---onDestroy()--->
SecondFragment: ---onDetach()--->
SecondActivity: ---onDestroy()--->
2. java代码绑定Fragment
**启动MainActivity
**
```
CustomeFragment fragment = new CustomeFragment();
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.container,fragment);
//transaction.replace(R.id.container,fragment);
```
MainActivity: ---onCreate()--->First
MainActivity: ---onCreate()--->Second
MainFragment: ---MainFragment()--->
MainFragment: ---onAttach()--->activity
MainFragment: ---onAttach()--->context
MainFragment: ---onCreate()--->
MainFragment: ---onCreateView()--->
MainFragment: ---onViewCreated()--->
MainFragment: ---onActivityCreated()--->
MainActivity: ---onStart()--->
MainFragment: ---onStart()--->
MainActivity: ---onResume()--->
MainFragment: ---onResume()--->
**启动SecondActivity
**
MainFragment: ---onPause()--->
MainActivity: ---onPause()--->
SecondActivity: ---onCreate()--->First
SecondActivity: ---onCreate()--->Second
SecondFragment: ---SecondFragment()--->
SecondFragment: ---onAttach()--->activity
SecondFragment: ---onAttach()--->context
SecondFragment: ---onCreate()--->
SecondFragment: ---onCreateView()--->
SecondFragment: ---onViewCreated()--->
SecondFragment: ---onActivityCreated()--->
SecondActivity: ---onStart()--->
SecondFragment: ---onStart()--->
SecondActivity: ---onResume()--->
SecondFragment: ---onResume()--->
MainFragment: ---onStop()--->
MainActivity: ---onStop()--->
**结束SecondActivity
**
SecondFragment: ---onPause()--->
SecondActivity: ---onPause()--->
MainActivity: ---onRestart()--->
MainActivity: ---onStart()--->
MainFragment: ---onStart()--->
MainActivity: ---onResume()--->
MainFragment: ---onResume()--->
SecondFragment: ---onStop()--->
SecondActivity: ---onStop()--->
SecondFragment: ---onDestroyView()--->
SecondFragment: ---onDestroy()--->
SecondFragment: ---onDetach()--->
SecondActivity: ---onDestroy()--->
## 常用类
1. android.app.Fragment 主要用于定义Fragment
2. android.app.FragmentManager用于获取FragmentTransaction
3. android.app.FragmentTransaction用于操作Fragment
## 常用方法
备注:Fragment通过FragmentManager开启事务(FragmentTransaction),然后通过transaction操纵Fragment,每个transaction只能提交(commit())一次。
如果遇到了Fragment嵌套Fragment的情况,内部的子Fragment要获取FragmentManager,要调用getChildFragmentManager();
* transaction.setCustomAnimations(@AnimRes int enter,@AnimRes int exit)--->设置动画
* transaction.add(@IdRes int containerViewId, Fragment fragment)--->添加Fragment
* transaction.remove(Fragment fragment)--->移除一个Fragment,如果不调用addToBackStack()方法将当前Fragment加入到回退栈中当前Fragment将会被销毁;加入到回退栈中当前Fragment只会销毁View(点击返回键Fragment将重新创建View并显示)
* transaction.replace(@IdRes int containerViewId, Fragment fragment)--->替换Fragment,实际上就是remove()+add()的合体,调用replace()方法时,如果不调用addToBackStack()方法将当前Fragment加入到回退栈中当前Fragment将会被销毁(调用onDetach())(再次显示此Fragment需要重新创建);加入到回退栈中当前Fragment只会销毁View(调用onDestroyView())(再次显示此Fragment只需重新创建View)
* transaction.hide(Fragment fragment)--->隐藏当前Fragment 调用hide()、show()不执行生命周期方法
* transaction.show(Fragment fragment)--->显示已经添加的Fragment
* transaction.detach(Fragment fragment)--->会将view从UI中移除销毁view
* transaction.attach(Fragment fragment)--->重建view视图,附加到UI上并显示
* transaction.commit()--->提交,commit后对Fragment的操作才生效,transaction只能提交一次
* fragment.isAdded()--->判断一个Fragment是否已经添加过
* fragment.isVisible()--->判断Fragment是否可见
* fragment.isResumed()--->判断Fragment是否聚焦
* fragment.isHidden()--->判断Fragment是否隐藏
* fragment.isRemoving()--->如果当前的Fragment对象正在从它的Activity中被删除,那么就返回true。这删除过程不是该Fragment对象的Activity的结束过程,而是把Fragment对象从它所在的Activity中删除的过程。
* fragment.isDetached()--->如果该Fragment已经明确的从UI中分离,那么它返回true。也就是说,在该Fragment对象上使用FragmentTransaction.detach(Fragment)方法。
* public void onActivityResult(int requestCode, int resultCode, Intent data)接收来自前面调用startActivityForResult(Intent, int)方法的结果
* Public View getView()获取该Fragment对象布局的根View对象,如果没有布局,则返回null。
* public void onConfigurationChanged(Configuration newConfig)
* public final int hashCode()子类不能覆盖重写该方法。返回对象的hash code
* public final Activity getActivity()返回跟该Fragment对象关联的Activity对象。
* public final Bundle getArguments()返回该Fragment对象被实例化时所提供的参数。
* public final FragmentManager getFragmentManager()
* public void onHiddenChanged(boolean hidden)
当该Fragment对象改变了隐藏状态(由isHidden()方法返回)时,系统会调用这个方法。Fragment初始是不隐藏的,只要Fragment对象改变了它的显示状态,就会调用该方法。
* public final int getId()
该方法返回该Fragment对象的标识,这个标识既可以是在布局中提供的android:id属性值,也可以是在添加Fragment对象时提供的容器View ID。
* public final String getTag()
如果Fragment对象被指定了名称,那么使用该方法来获取Fragment对象的名称。
* public LoaderManager getLoaderManager()
返回针对该Fragment对象的LoaderManager对象,如果需要就创建它。
* public final Resources getResources()
该方法返回跟Fragment对象关联的资源。
* public final String getString(int resId)
从应用程序包的默认字符串表中返回一个本地化的字符串。
* public final Fragment getTargetFragment()
返回由setTargetFragment(Fragment, int)方法所设置的目标Fragment对象。
* public final int getTargetRequestCode()
返回由setTargetFragment(Fragment, int)方法所设置的目标请求编码。
* public final CharSequence getText(int resId)
从应用程序包的默认字符串表中返回指定的本地化的、样式化的CharSequence对象。
* public final getUserVisibleHint()
返回要该Fragment对象上显示给用户的提示信息的值。
* public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo)
当View对象相关的上下文菜单显示的时候,系统会调用该方法。跟onCreateOptionMenu(Menu, MenuInflater)不同,这个方法在上下文菜单每次显示的时候,都会被调用,并且应该被填入对应的View对象。
使用onContextItemSelected(android.view.MenuItem)方法来获取被选择的菜单项。(onCreateOptionMenu()只执行一次, onCreateContextMenu()执行多次)
* public boolean onContextItemSelected(MenuItem item)
在上下文菜单中的一个菜单项被选择时,系统会调用这个回调方法。对于所放生的普通的处理过程,该方法的默认实现只是简单的返回false(调用该项目的Runnable对象或把一个消息发送给相应的Handler)。可以使用这个方法针对菜单项做一些其他的处理。使用getMenuInfo()方法来获取由添加给菜单项的View对象所设置的附加信息。如果允许正常的上下文菜单处理,就返回false,否则返回true。
* public Animator onCreateAnimator(int transit, boolean enter, int nextAnim)
在Fragment对象加载一个动画时,系统会调用这个方法。
* public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
该方法初始化Activity的标准的选项菜单的内容。应该把菜单项放到menu参数中。针对该方法的调用,必须要首先调用setHasOptionsMenu(boolean)方法。更多信息请看Activity.onCreateOptionsMenu。
* Public void onDestroyOptionsMenu()
当该Fragment的选项菜单项目不再被包含在整体的选项菜单中时,系统会调用该方法。收到这个调用,意味着该菜单需要被重建,但是这个Fragment的项目没有被包含在最新创建的菜单中(Fragment的onCreateOptionsMenu(Menu, MenuInflater)方法不会被调用)。
## Fragment与ActionBar和MenuItem集成
Fragment可以添加自己的MenuItem到Activity的ActionBar或者可选菜单中。
* a、在Fragment的onCreate中调用setHasOptionsMenu(true);
* b、然后在Fragment子类中实现onCreateOptionsMenu
* c、如果希望在Fragment中处理MenuItem的点击,也可以实现onOptionsItemSelected;当然了Activity也可以直接处理该MenuItem的点击事件。
## Fragment的其它子类
### DialogFragment
显示一个浮动的对话框. 用这个类来创建一个对话框,是使用在Activity类的对话框工具方法之外的一个好的选择,因为你可以将一个fragment对话框合并到activity管理的fragment back stack中,允许用户返回到一个之前曾被摒弃的fragment.
### ListFragment
显示一个由一个adapter(例如 SimpleCursorAdapter)管理的项目的列表, 类似于ListActivity。它提供一些方法来管理一个list view, 例如 onListItemClick()回调来处理点击事件,setListAdapter()设置适配器.
### PreferenceFragment
显示一个 Preference对象的层次结构的列表, 类似于PreferenceActivity。这在为你的应用创建一个"设置"activity时有用处.
```
解决ViewPager预加载问题,显示才加载
public abstract class LazyLoadFragment extends Fragment {
// View是否创建
protected boolean viewInitiated;
// 用户是否可见
protected boolean visibleToUser;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
viewInitiated = true;
prepareFetchData();
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
this.visibleToUser = isVisibleToUser;
prepareFetchData();
}
/**
* 获取数据
*/
public abstract void fetchData();
public boolean prepareFetchData() {
if (visibleToUser && viewInitiated) {
fetchData();
return true;
}
return false;
}
@Override
public void onDestroyView() {
super.onDestroyView();
viewInitiated = false;
}
}
```
# ViewPager
* FragmentPagerAdapter保存所有Fragment超出setOffscreenPageLimit的销毁View即onDestroyView()
* FragmentStatePagerAdapter保留状态销毁Fragment执行onDetach()
* viewPager.setOffscreenPageLimit(1)--->设置预览的数量
* mViewPager.setPageMargin(30)--->设置viewpager每个页面之间的间距
## ViewPager点击
```
final long[] downTime = {0};
final float[] downX = {0};
final float[] downY = {0};
mViewPager.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
downTime[0] = System.currentTimeMillis();
downX[0] = motionEvent.getX();
downY[0] = motionEvent.getY();
// ToDo
break;
case MotionEvent.ACTION_CANCEL:
// ToDo
break;
case MotionEvent.ACTION_UP:
long upTime = System.currentTimeMillis();
float upX = motionEvent.getX();
float upY = motionEvent.getY();
if (upTime - downTime[0] < 200 && Math.abs(upX - downX[0]) < 30 && Math
.abs(upY - downY[0]) < 30) {
// ToDo
} else {
// ToDo
}
break;
}
return false;
}
});
```
# TabLayout
1. app:tabContentStart="100dp" TabLayout开始位置的偏移量
2. app:tabMode="scrollable" TabLayout的模式
3. app:tabTextAppearance="@style/tabLayoutTextAppearance" TabLayout设置文字样式
4. app:tabPadding="5dp" tab的内边距
5. app:tabBackground="@null" 去掉tab点击的阴影
* TabLayout.Tab tab = tabLayout.newTab()--->创建tab
* tabLayout.addTab(tab)--->添加tab
* tabLayout.removeTab(tab)--->删除tab
* tabLayout.removeAllTabs()--->删除所有tab
* tabLayout.removeTabAt(0)--->删除指定位置tab
* TabLayout.Tab tabAt = tabLayout.getTabAt(0)--->通过position获得tab
* int tabCount = tabLayout.getTabCount()--->标签总数
* int selectedTabPosition = tabLayout.getSelectedTabPosition()--->获得选择的tab的position
## tab的方法
* tab.setText("go")--->设置文字
* tab.setIcon(R.mipmap.ic_launcher_round)--->设置icon
* tab.setTag("u")--->设置标签
* Object tag = tab.getTag()--->获取标签
* int position = tab.getPosition()--->获得position
* boolean selected = tab.isSelected()--->判断是否被选择
* tab.select()--->设置为被选择状态
```
自定义tab
View view = LayoutInflater.from(this).inflate(R.layout.tab, null);
tab.setCustomView(view);
tabLayout.addTab(tab, 0);
```