PagerSlidingTabStrip source code parsing, pagerslidingtabstrip
PagerSlidingTabStrip source code analysis
This article describes $ {PagerSlidingTabStrip} in the source code analysis of the Android open-source project.
Project address :[ PagerSlidingTabStrip] ( {Https://github.com/astuetz/PagerSlidingTabStrip}), analyzed version: 1.0.1, Demo address: PagerSlidingTabStrip Demo
Analyzer: ayyb1988, analysis status: Completed
Proofreader:, proofreader Status: Not started
Demo effect:
The preceding tab is textviewtab. The following tab is icontab.
1. Overall Design
PagerSlidingTabStrip is referenced by OnPageChangeListener of ViewPager.
However, the listener registered by viewpager is not its own OnPageChangeListener, but the internal class PageListener of pagerSlidingTabStrip.
Use PageListener to encapsulate viewpager and tab. To achieve the sliding linkage effect.
You can set the tab type to textview or icon. You can set Font attributes for textview.
You can customize the effect by providing methods such as sliding indicator underline tab style line tab weight.
2. Flowchart
3. Features
3.1 features
- Compatible with a sliding paging indicator control of ViewPager In the Android library.
- Achieve interaction of TextView color status during sliding
- Supports text navigation instructions to specify the selected pager navigation font attributes
- Supports image navigation instructions to highlight and select the pager page navigation background
- Good scalability
3.2 Integration and User Guide3.2.1
In gradle, dependencies {compile 'com. astuetz: pagerslidingtabstrip: 1.0.1 '}
3.2.2 introduce PagerSlidingTabStrip in the layout file, which is usually laid on viewpager. As follows:
" data-snippet-id="ext.70f9ac1ecd734202407c447517d62cfb" data-snippet-saved="false" data-codota-status="done"><com.astuetz.PagerSlidingTabStrip android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="48dip" />
3.2.3 bind PagerSlidingTabStrip to Viewpager in the oncreate method (or the onCreateView of Fragment)
// Initialize ViewPager and Adapter ViewPager pager = (ViewPager) findViewById (R. id. pager); pager. setAdapter (new TestAdapter (getsuppfrfragmentmanager (); // bind PagerSlidingTabStrip to PagerSlidingTabStrip tabs = (PagerSlidingTabStrip) findViewById (R. id. tabs); tabs. setViewPager (pager );
3.2.4 If your view pager uses OnPageChangeListener. You should use this PagerSlidingTabStrip control instead of Viewpager. As follows:
// continued from above tabs.setOnPageChangeListener(mPageChangeListener);
3.3 user customization
Modify the following values as needed
4. Detailed Design
4.1 class details
4.2 Core methods and functions
PagerSlidingTabStrip is referenced by OnPageChangeListener of ViewPager. However, the listener registered by viewpager is not its own OnPageChangeListener, but the internal class PageListener of pagerSlidingTabStrip. Use PageListener to encapsulate viewpager and tab. To achieve the sliding linkage effect. The following is a detailed description of the Code.
Private class PageListener implements OnPageChangeListener {@ Override public void onPageScrolled (int position, float positionOffset, int positionOffsetPixels) {// the position of the current view is also the position of the tab currentPosition = position; // The sliding distance of the current view. CurrentPositionOffset is float, ranging from 0 ~ 1 represents the ratio of currentPositionOffset = positionOffset to the tab width offset; // synchronize the tab position and offset distance based on The view position and offset position obtained above. ScrollToChild (position, (int) (positionOffset * tabsContainer. getChildAt (position). getWidth (); // re-paint the view to achieve tab sliding. Invalidate (); // The delegatePageListener below is the viewpager. setOnPageChangeListener we set. Now we encapsulate it in the whole pagerSlidingTabStrip to achieve the effect of viewpager sliding. If (delegatePageListener! = Null) {delegatePageListener. onPageScrolled (position, positionOffset, positionOffsetPixels) ;}@override public void onPageScrollStateChanged (int state) {// The sliding ends. PositionOffset to zero if (state = ViewPager. SCROLL_STATE_IDLE) {scrollToChild (pager. getCurrentItem (), 0);} // call viewpager. setOnPageChangeListener if (delegatePageListener! = Null) {delegatePageListener. onPageScrollStateChanged (state) ;}}@ Override public void onPageSelected (int position) {// call viewpager. setOnPageChangeListener if (delegatePageListener! = Null) {delegatePageListener. onPageSelected (position );}}}
ScrollToChild: The sliding position of the tab is implemented as follows:
Private void scrollToChild (int position, int offset) {if (tabCount = 0) {return;} int newScrollX = tabsContainer. getChildAt (position ). getLeft () + offset; if (position> 0 | offset> 0) {newScrollX-= scroloffset;} // slide to the position. If (newScrollX! = LastScrollX) {lastScrollX = newScrollX; scrollTo (newScrollX, 0 );}}
Next let's talk aboutAddTextTabAndAddIconTab. That is, whether the tab is text or icon. If it is an icon, use the adapter of viewpager to implement the IconTabProvider interface. To determine the icontab.
for (int i = 0; i < tabCount; i++) { if (pager.getAdapter() instanceof IconTabProvider) { addIconTab(i, ((IconTabProvider) pager.getAdapter()).getPageIconResId(i)); } else { addTextTab(i, pager.getAdapter().getPageTitle(i).toString()); } }
4.3 View rendering Mechanism
See the public technical point viewdrawflow Section
The onDraw function is rewritten in pagerSlidingTabStrip.
Draw slide indicator; draw the entire tabs underline; draw the line between tabs.The Code is as follows:
// draw indicator line rectPaint.setColor(indicatorColor); // default: line below current tab View currentTab = tabsContainer.getChildAt(currentPosition); float lineLeft = currentTab.getLeft(); float lineRight = currentTab.getRight(); // if there is an offset, start interpolating left and right coordinates between current and next tab if (currentPositionOffset > 0f && currentPosition < tabCount - 1) { View nextTab = tabsContainer.getChildAt(currentPosition + 1); final float nextTabLeft = nextTab.getLeft(); final float nextTabRight = nextTab.getRight(); lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) * lineLeft); lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset) * lineRight); } canvas.drawRect(lineLeft, height - indicatorHeight, lineRight, height, rectPaint); // draw underline rectPaint.setColor(underlineColor); canvas.drawRect(0, height - underlineHeight, tabsContainer.getWidth(), height, rectPaint); // draw divider dividerPaint.setColor(dividerColor); for (int i = 0; i < tabCount - 1; i++) { View tab = tabsContainer.getChildAt(i); canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint); }
5. Miscellaneous
This database has good customization and scalability. For example, you can change the slide indicator to an image (currently determined by the set color and height]
References
ViewPagerindicator source code analysis
View rendering: Demo download of TOUCH event processing