Viewpagerindicator Imitation of NetEase News tab or the Discovery tab

Source: Internet
Author: User

tab is often useful to such as NetEase news, the effect of the request can be sliding, the following instructions, when the tab page beyond the screen of the content also to follow the move.

The effect of the indicator many people will use the tabpageindicator, here we refer to http://blog.csdn.net/lmj623565791/article/details/42160391 to write their own indicators.


There are a total of three components,

There's a linearlayout in Horizontalscrollview that can add our view,

Viewpagerindicator Our indicator

Viewpager to put content fragment

The layout is as follows

<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:backg Round= "#ffffff" android:orientation= "vertical" > 2. The emphasis is on the logic of Viewpagerindicator, we use the knowledge of custom controls here, and do not know how to view my previous article on how to customize the control, the indicator is to use a linearlayout

Package Com.example.demotab;import Java.util.list;import Android.annotation.suppresslint;import Android.content.context;import Android.content.res.typedarray;import Android.graphics.canvas;import Android.graphics.color;import Android.graphics.cornerpatheffect;import Android.graphics.paint;import Android.graphics.paint.style;import Android.graphics.path;import Android.support.v4.view.viewpager;import Android.support.v4.view.viewpager.onpagechangelistener;import Android.util.attributeset;import Android.util.displaymetrics;import Android.util.log;import Android.util.typedvalue;import android.view.Gravity; Import Android.view.view;import Android.view.windowmanager;import Android.widget.horizontalscrollview;import Android.widget.linearlayout;import Android.widget.relativelayout;import android.widget.textview;/** * * * @author Chaoyue * */public class Viewpagerindicator extends LinearLayout {/** * draw triangle Brush */private paint mpaint;/** * path makes a triangle */private Path mpath;/** * Triangle width */privateint mtrianglewidth;/** * triangle height */private int mtriangleheight;/** * Triangle width is single tab 1/6 */private static final float RADIO_TR Iangel = 1.0f/6;/** * Maximum width of the triangle */private final int dimension_triangel_width = (int) (Getscreenwidth ()/3 * Radio_triang EL);/** * Initial, the offset of the triangle indicator */private int minittranslationx;/** * Offset when the finger is sliding */private float mtranslationx;/** * Tab Content */PRI Vate list<view> mtabtitles;/** * binding Viewpager */public viewpager mviewpager;/** * Sub View is square width */private int child viewwidth;/** * Bound Horizontalscrollview */private Horizontalscrollview horizontalscrollview;public Viewpagerindicator (Context context) {This (context, null);} Public Viewpagerindicator (context context, AttributeSet Attrs) {Super (context, attrs);//initialization Brush mpaint = new Paint (); Mpaint.setantialias (True); Mpaint.setcolor (Color.parsecolor ("#ffffffff")); Mpaint.setstyle (Style.fill); Mpaint.setpatheffect (New Cornerpatheffect (3)); if (childviewwidth = = 0) {childviewwidth = 300;}} public void setchildviewwidth (int childviewwIdth) {this.childviewwidth = Childviewwidth;} public void Sethorizontalscrollview (Horizontalscrollview horizontalscrollview) {This.horizontalscrollview = Horizontalscrollview;} /** * Draw indicator */@Overrideprotected void Dispatchdraw (canvas canvas) {canvas.save ();//brush pan to the correct position canvas.translate ( Minittranslationx + Mtranslationx, getheight () + 1); Canvas.drawpath (MPath, Mpaint); Canvas.restore (); Super.dispatchdraw (canvas);}  /** * Initialize the width of the triangle */@Overrideprotected void onsizechanged (int w, int h, int oldw, int oldh) {super.onsizechanged (W, H, OLDW, OLDH); mtrianglewidth = (int) (W/4 * Radio_triangel);//1/6 of//widthmtrianglewidth = math.min (dimension_triangel_width , mtrianglewidth);//Initialize triangle Inittriangle ();//initial offset Minittranslationx = CHILDVIEWWIDTH/2-MTRIANGLEWIDTH/2;} /** * Set tab title Content optional, you can write in the layout file dead * * @param datas */public void Settabitemtitles (list<view> datas) {//If the incoming List has a value, Remove the viewif set in the layout file (datas! = null && datas.size () > 0) {this.removeallviews (); this.mtabtitles = datas;for (int i = 0; i < datas.size (); i++) {AddView (Datas.get (i), childviewwidth, childviewwidth);} Set item's Click event Setitemclickevent ();}} /** * External Viewpager Callback interface * * @author zhy * */public interface Pagechangelistener {public void onpagescrolled (int position , float positionoffset,int positionoffsetpixels);p ublic void onpageselected (int position);p ublic void onpagescrollstatechanged (int state);} Callback interface for external Viewpager private Pagechangelistener onpagechangelistener;//setting of the callback interface of the external viewpager public void Setonpagechangelistener (Pagechangelistener pagechangelistener) {this.onpagechangelistener = PageChangeListener;} Sets the associated viewpagerpublic void Setviewpager (Viewpager mviewpager, int pos) {this.mviewpager = Mviewpager; Mviewpager.setonpagechangelistener (New Onpagechangelistener () {@Overridepublic void onpageselected (int position) {// Callback if (Onpagechangelistener! = null) {onpagechangelistener.onpageselected (position);}} @Overridepublic void onpagescrolled (int position, float positionoffset,int POSitionoffsetpixels) {//scroll scroll (position, positionoffset);//callback if (Onpagechangelistener! = null) { Onpagechangelistener.onpagescrolled (Position,positionoffset, positionoffsetpixels);}} @Overridepublic void onpagescrollstatechanged (int state) {//callback if (Onpagechangelistener! = null) { Onpagechangelistener.onpagescrollstatechanged (state);}}); /Set Current page Mviewpager.setcurrentitem (POS);//Highlight}/** * Set Click event */public void Setitemclickevent () {linearlayout layout = (Linear Layout) horizontalscrollview.getchildat (0); int ccount = Layout.getchildcount (); for (int i = 0; i < ccount; i++) {final int j = i; View view = Layout.getchildat (i); View.setonclicklistener (new Onclicklistener () {@Overridepublic void OnClick (view v) { Mviewpager.setcurrentitem (j);}});}} /** * Initialize triangle indicator */private void Inittriangle () {MPath = new Path (); mtriangleheight = (int) (MTRIANGLEWIDTH/2/Math.sqrt ( 2); Mpath.moveto (0, 0); Mpath.lineto (mtrianglewidth, 0); Mpath.lineto (MTRIANGLEWIDTH/2,-mtriangleheight); Mpath.close ();} /** * Indicator withFinger scrolling, and container scrolling * * @param position * @param offset */float lasthx = 0;public void scroll (int position, float offset) {int T Abwidth = Childviewwidth;int tabvisible = getwidth ()/Tabwidth;float right = Tabwidth-(getwidth ()-tabvisible * TabWid th); Mtranslationx = Childviewwidth * (position + offset); if (Getchildcount () * tabwidth-getwidth () > 0) {if (offset & Gt 0.0001f && position + 1 >= tabvisible) {if (position + 2 >= getchildcount () && offset > 0.0001f) {int x = (int) (LASTHX + right * offset); This.scrollto (x, 0); Horizontalscrollview.scrollto (x, 0); Horizontalscrollview.invalidate ();} else {int x = (int) (Tabwidth * (position + 1 + offset-tabvisible)) This.scrollto (x, 0); lasthx = X;horizontalscrollview. ScrollTo (x, 0); Horizontalscrollview.invalidate ();}}} Invalidate ();} /** * Get the width of the screen * * @return */public int getscreenwidth () {WindowManager wm = (WindowManager) getcontext (). Getsystemservice (context.window_service);D isplaymetrics outmetrics = new DisplaymEtrics (); Wm.getdefaultdisplay (). Getmetrics (outmetrics); return outmetrics.widthpixels;}} 

The main focus is to understand a few questions: Initialize the triangles and move the triangles to move the Carvas

/** * Initialize triangle indicator */private void Inittriangle () {MPath = new Path (); mtriangleheight = (int) (MTRIANGLEWIDTH/2/Math.sqrt ( 2); Mpath.moveto (0, 0); Mpath.lineto (mtrianglewidth, 0); Mpath.lineto (MTRIANGLEWIDTH/2,-mtriangleheight); Mpath.close ();}

/** * Draw indicator */@Overrideprotected void Dispatchdraw (canvas canvas) {canvas.save ();//brush pan to the correct position canvas.translate ( Minittranslationx + Mtranslationx, getheight () + 1); Canvas.drawpath (MPath, Mpaint); Canvas.restore (); Super.dispatchdraw (canvas);}

and the triangle certain distance needs the parameter is in Viewpager's movement monitoring onpagerlisnear method, I wrote a method

/** * Indicator follows finger scrolling, as well as container scrolling *  * @param position * @param offset */float lasthx = 0;public void scroll (int position, float o Ffset) {int tabwidth = Childviewwidth;int tabvisible = getwidth ()/Tabwidth;float right = Tabwidth-(getwidth ()-TabVis ible * tabwidth); Mtranslationx = Childviewwidth * (position + offset); if (Getchildcount () * tabwidth-getwidth () > 0) {if (offset > 0.0001f && position + 1 >= tabvisible) {if (position + 2 >= getchildcount () && offs ET > 0.0001f) {int x = (int) (LASTHX + right * offset); This.scrollto (x, 0); Horizontalscrollview.scrollto (x, 0); Horizont Alscrollview.invalidate ();} else {int x = (int) (Tabwidth * (position + 1 + offset-tabvisible)) This.scrollto (x, 0); lasthx = X;horizontalscrollview. ScrollTo (x, 0); Horizontalscrollview.invalidate ();}}} Invalidate ();}
One thing to note in the code is that the triangle moves beyond the screen when you want to display it, itself this linearlayout must also move, the above Horizontalscrollview also follow the move can be done with the content and tab also follow the effect of moving.

The difference between what I do and the rest is that if the tab page goes out of the screen, I'm sliding closer to the last one in the screen to control the content, tab, and move.

Look at mainactivity again.

Package Com.example.demotab;import Java.lang.reflect.array;import Java.util.arraylist;import java.util.Arrays; Import Java.util.list;import android.app.activity;import android.os.bundle;import android.support.v4.app.Fragment; Import Android.support.v4.app.fragmentactivity;import Android.support.v4.app.fragmentpageradapter;import Android.support.v4.view.viewpager;import Android.view.gravity;import Android.view.menu;import Android.view.menuitem;import Android.view.view;import Android.widget.horizontalscrollview;import Android.widget.linearlayout;import Android.widget.textview;public class Mainactivity extends FragmentActivity { Private list<fragment> mtabcontents = new arraylist<fragment> ();p rivate fragmentpageradapter mAdapter; Private Viewpager mviewpager;private list<view> mdatas = new arraylist<view> ();p rivate ViewPagerIndicator mindicator;private horizontalscrollview horizontalscrollview;private int tabwidth;private LinearLayout llLayout; Private List<string> List = arrays.aslist ("Column One", "column Two", "column Three", "column Four", "Column Five", "column Six", "Column Seven", "column Eight"); @Overrideprotected void OnCreate (Bundle saved Instancestate) {super.oncreate (savedinstancestate); Setcontentview (r.layout.activity_main); MViewPager = (ViewPager ) Findviewbyid (R.ID.VP); mindicator = (viewpagerindicator) Findviewbyid (r.id.indicator); lllayout = (LinearLayout) Findviewbyid (R.ID.LL1); Horizontalscrollview = (Horizontalscrollview) Findviewbyid (R.ID.HSV); tabWidth = This.getresources (). Getdimensionpixeloffset (R.dimen.text_w); for (int i = 0; i < list.size (); i++) {Mdatas.add (new View (this)); TextView TextView = new TextView (this); Textview.settext (List.get (i)); textview.setgravity (Gravity.center); Linearlayout.layoutparams layoutparams = new Linearlayout.layoutparams (Tabwidth, LinearLayout.LayoutParams.FILL_ PARENT); Lllayout.addview (textview,layoutparams); Mtabcontents.add (Maintab.newinstance (List.get (i))); Madapter = new Fragmentpageradapter (Getsupportfragmentmanager ()) {@Overridepublic int getcount () {RetuRN mtabcontents.size ();} @Overridepublic Fragment getItem (int position) {return mtabcontents.get (position);}}; Mindicator.setchildviewwidth (tabwidth); Mindicator.sethorizontalscrollview (Horizontalscrollview); Mindicator.settabitemtitles (Mdatas);//Set the associated Viewpagermviewpager.setadapter (madapter); Mviewpager.setcurrentitem ( 0); Mindicator.setviewpager (Mviewpager, 0);} @Overridepublic boolean Oncreateoptionsmenu (Menu menu) {//Inflate the menu; This adds items to the action bar if it is PR Esent.getmenuinflater (). Inflate (R.menu.main, menu); return true;} @Overridepublic boolean onoptionsitemselected (MenuItem Item) {//Handle Action Bar item clicks here. The action bar will//automatically handle clicks on the Home/up button so long//as you specify a parent activity in and RoidManifest.xml.int id = item.getitemid (); if (id = = r.id.action_settings) {return true;} return super.onoptionsitemselected (item);}}

The source code, etc. issued

Viewpagerindicator Imitation of NetEase News tab or the Discovery tab

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.