# 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); ```