Android anti-web page sliding switch between left and right, android anti-micro
You can see whether the Home Page switching effect is very dazzling, sliding switch, click the bar at the bottom to instantly switch, sliding switch gradient effect, online:
I have also seen other people's implementations on my blog. On the basis of this, I have made some optimizations. First, let's talk about the implementation principle.
Three Fragment pages are displayed on the page, and viewpager is slide on the left and right. I believe this is the case for everyone. What technology is used at the bottom, the bottom gradient actually overwrites the ImageView and changes the color value of the TextView when the Left and Right slides. Is it very simple... next, let's take a step:
1. Custom ImageView:
/*** Initialize the resource image bitmap and related drawing objects * @ param normal normals * @ param selected focus */public final void init (int normal, int selected, int width, int height) {this. mNormalIcon = createBitmap (normal); this. mSelectedIcon = createBitmap (selected); this. mNormalRect = new Rect (0, 0, width, height); this. mSelectedRect = new Rect (0, 0, width, height); this. mPaint = new Paint (1 );}
Two bitmaps are defined here, which correspond to the Bitmap image displayed when the focus is obtained and when the focus is lost. The two matrices are used during the Painting Process and define an externally called method, during the sliding between the left and right sides, the transparency value is changed through the offset value. The superposition of the two images is the corresponding excessive effect.
Then, you can refresh the view during the sliding process to re-draw the view. The onDraw rewrite method is provided as follows:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (this.mPaint == null) { return; } this.mPaint.setAlpha(255 - this.mSelectedAlpha); canvas.drawBitmap(this.mNormalIcon, null, this.mNormalRect, this.mPaint); this.mPaint.setAlpha(this.mSelectedAlpha); canvas.drawBitmap(this.mSelectedIcon, null, this.mSelectedRect, this.mPaint); }
Here we can see that the companion Paint changes the transparency of the incoming two bitmaps to achieve the gradient effect. mSelectedAlpha is the transparency value of the external incoming bitmap.
2. Customize the bar container at the bottom of the Implementation. Here we will rewrite the LinearLayout implementation (called container) to do the following in the container:
1) define the external interface to call and receive the resource information displayed at the bottom:
A. initialization parameters:
public void initContainer (String[] titles, int[][] iconsRes, int[] colors, boolean showTransitionColor) { this.mTitles = titles; this.mIconRes = iconsRes; this.mTextNormalColor = getResources().getColor(colors[0]); this.mTextSelectedColor = getResources().getColor(colors[1]); this.mShowTransitionColor = showTransitionColor; }
The text array displayed on the tab, the image resource array displayed, the default color, and the color value array (array size = 2) when the focus is obtained, and whether to display the transition effect when switching.
B. Set the Control ID in the layout file and layout file, and the image width and height parameters when the image is displayed. Three methods are provided:
① Text tab:
/*** Set the layout file and Related Control id * @ param layout File id * @ param iconId ImageView Control id <= 0, not displayed * @ param textId TextView Control id when id <= 0, * @ param width icon width * @ param height icon height */public void setContainerLayout (int layout, int iconId, int textId, int width, int height) {mLayoutId = layout; mTextViewId = textId; mIconVIewId = iconId; mIconWidth = width; mIconHeight = height ;}
In the layout and tab layout files, the iconId corresponds to the resource Id of the custom ImageView, The textId corresponds to the Id of the TextView, and the width and height indicate the width and height of the image display.
② Only text tab: Input iconId when only text tab is displayed
③ Only the image tab: correspondingly, the text textId = 0 can be input in the method provided by the graphic tab.
C. Inject ViewPager: You need to monitor the sliding of ViewPager to change the gradient.
2). Add a tab to container:
Here, you need to determine whether the iconId and TextId are greater than 0. If it is equal to 0, it is not displayed. At the same time, in order to center and divide the length of the bottom container, all tabs are equal to the bottom container.
/*** <P> Add tab view to current container </p> */private void addTabViewToContainer () {final PagerAdapter adapter = mViewPager. getAdapter (); mTabView = new View [adapter. getCount ()]; // determine the total number of tabs to be displayed at the bottom of the adapter for (int index = 0, len = adapter. getCount (); index <len; index ++) {final View tabView = LayoutInflater. from (getContext ()). inflate (mLayoutId, this, false); // load the tab layout mTabView [index] = tabView;/* tabIconView Initialize */TabIconView iconView = null; if (mIconVIewId> 0) {// if the input image resource file ID is not 0, the icon must be displayed, then initialize the View iconView = (TabIconView) tabView. findViewById (mIconVIewId); iconView. init (mIconRes [index] [0], mIconRes [index] [1], mIconWidth, mIconHeight ); // The init method of custom ImageView is called here}/* tabTextView initialization */TextView textView = null; if (mTextViewId> 0) {textView = (TextView) tabView. findViewById (mTextViewId); textView. SetText (mTitles [index]);}/* set the width, equals container */LayoutParams lp = (LayoutParams) tabView. getLayoutParams (); lp. width = 0; lp. weight = 1;/* Add a tab Click Event */addTabOnClickListener (tabView, index);/* set the current status */if (index = mViewPager. getCurrentItem () {// display the tab first and set the initial status to get the focus status if (iconView! = Null) {iconView. offsetChanged (0);} tabView. setSelected (true); if (textView! = Null) {textView. setTextColor (mTextSelectedColor) ;}} addView (tabView );}}
3) Listen to the sliding event of viewPager and update the container Based on the offset value to complete the repainting operation.
4). Calculate the transparent value based on the offset in the onDraw of the container. Here, the text offset value is calculated using an open source code.
@ Override protected void onDraw (Canvas canvas) {super. onDraw (canvas); final int childCount = getChildCount (); if (childCount> 0) {/* When an offset occurs, draw the gradient area */if (mSelectionOffset> 0f & mSelectedPosition <(getChildCount ()-1) & mShowTransitionColor) {/* obtain the current tab and the next tab view */View selectedTab = getChildAt (mSelectedPosition); View nextTab = getChildAt (mSelectedPosition + 1);/* When the tab icon is displayed, refresh the respective view transparency */if (mIconVIewId> 0) {View selectedIconView = selectedTab. findViewById (mIconVIewId); View nextIconView = nextTab. findViewById (mIconVIewId); // draw icon alpha if (selectedIconView instanceof TabIconView & nextIconView instanceof TabIconView) {(TabIconView) selectedIconView ). offsetChanged (mSelectionOffset); (TabIconView) nextIconView ). offsetChanged (1-mSelectionOffset);}/* display tab text, refresh the transparency of each view */if (mTextViewId> 0) {View selectedTextView = selectedTab. findViewById (mTextViewId); View nextTextView = nextTab. gradient (mTextViewId); // draw text color Integer selectedColor = (Integer) evaluate (mSelectionOffset, mTextSelectedColor, mTextNormalColor); Integer nextColor = (Integer) evaluate (1-mSelectionOffset, mTextSelectedColor, mTextNormalColor); if (selectedTextView instanceof TextView & nextTextView instanceof TextView) {(TextView) selectedTextView ). setTextColor (selectedColor); (TextView) nextTextView ). setTextColor (nextColor );}}}}}
3. Define a FragmentAdapter. This is skipped and it is relatively simple.
4. After the above preparations, you can write a test example to test the effect. Of course, to see the effect, we need to prepare several images and several fragment images in advance.
Private void initViews (){
// Obtain apdater TabFragmentAdapter mAdapter = new TabFragmentAdapter (outputs (), fragments); ViewPager mPager = (ViewPager) findViewById (R. id. tab_pager); mPager. setAdapter (mAdapter );
// If the current class needs to listen to the viewPager, TabContainerView mTabLayout = (TabContainerView) findViewById (R. id. ll_tab_container); mTabLayout. setOnPageChangeListener (this); mTabLayout. initContainer (getResources (). getStringArray (R. array. tab_main_title), ICONS_RES, TAB_COLORS, true); int width = getResources (). getDimensionPixelSize (R. dimen. tab_icon_width); int height = getResources (). getDimensionPixelSize (R. dimen. tab_icon_height); mTabLayout. setContainerLayout (R. layout. tab_container_view, R. id. iv_tab_icon, R. id. TV _tab_text, width, height); // mTabLayout. setSingleTextLayout (R. layout. tab_container_view, R. id. TV _tab_text); // mTabLayout. setSingleIconLayout (R. layout. tab_container_view, R. id. iv_tab_icon); mTabLayout. setViewPager (mPager); mPager. setCurrentItem (getIntent (). getIntExtra ("tab", 0 ));}
The xml corresponding to ManActivity is relatively simple. You can refer to the source code, and the final running effect is the above texture. The anti-sliding switch is complete. For the source code, visit the following link:
Source code download: https://github.com/JarekWang/wechathome.git