Android Viewpager implementation of sliding bar and fragment with the example tutorial _android

Source: Internet
Author: User
Tags stub

Self-implementing sliding indicator Bar
First, a basic effect chart:

1.XML layout
The layout code 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:orientation= "vertical" 
 tools:context= "com.example.testviewpage_2.MainActivity" > 
  
  < ImageView 
  android:id= "@+id/cursor" 
  android:layout_width= "Fill_parent" 
  Wrap_content " 
  android:scaletype=" Matrix " 
  android:src=" @drawable/a "/> 
 
 < Android.support.v4.view.ViewPager 
  android:id= "@+id/viewpager" 
  android:layout_width= "Wrap_content" 
  android:layout_height= "wrap_content" 
  android:layout_gravity= "center"/> 
 
</linearlayout > 

With a linear vertical layout, add a small horizontal bar above the sliding page.

2.JAVA Code

public class Mainactivity extends activity {private View view1, View2, VIEW3; Private list<view> viewlist;//View array private Viewpager Viewpager; 
 The corresponding Viewpager private imageview cursor; private int BMPW = 0; Cursor width private int offset = 0;////animation picture offset private int currindex = 0;//Current page card number @Override protected void Oncrea 
  Te (Bundle savedinstancestate) {super.oncreate (savedinstancestate); 
 
  Setcontentview (R.layout.activity_main); 
  Viewpager = (Viewpager) Findviewbyid (R.id.viewpager); 
  Layoutinflater inflater = Getlayoutinflater (); 
  View1 = inflater.inflate (R.LAYOUT.LAYOUT1, NULL); 
  View2 = inflater.inflate (r.layout.layout2, NULL); 
 
  VIEW3 = inflater.inflate (R.LAYOUT.LAYOUT3, NULL); 
  Viewlist = new arraylist<view> ()//The View to be displayed is loaded into the array viewlist.add (VIEW1); 
  Viewlist.add (VIEW2); 
 
  Viewlist.add (VIEW3); 
   
  Initialize indicator position initcursorpos (); 
  Viewpager.setadapter (New Mypageradapter (viewlist)); Viewpager.setonpagechangelistenER (new Mypagechangelistener ()); 
  }//Initialize indicator position public void Initcursorpos () {//Initialize animation cursor = (ImageView) Findviewbyid (r.id.cursor); BMPW = Bitmapfactory.decoderesource (Getresources (), R.drawable.a). GetWidth ()//Get picture width displaymetrics dm = new 
  Displaymetrics (); 
  Getwindowmanager (). Getdefaultdisplay (). Getmetrics (DM); int screenw = dm.widthpixels;//Get resolution width offset = (screenw/viewlist.size ()-BMPW)/2;//compute offset Matrix matrix = n 
  EW Matrix (); 
  Matrix.posttranslate (offset, 0); Cursor.setimagematrix (matrix),//Set animation initial position}//page change Listener public class Mypagechangelistener implements Onpagechange 
  Listener {int one = offset * 2 + bmpw;//page card 1-> page Card 2 offset int two = one * 2;//page Card 1-> page Card 3 offset @Override 
   public void onpageselected (int arg0) {Animation Animation = null; 
    Switch (arg0) {case 0:if (currindex = = 1) {animation = new Translateanimation (one, 0, 0, 0); 
     else if (Currindex = 2) {Animation = new Translateanimation (two, 0, 0, 0); 
   } break; 
    Case 1:if (Currindex = = 0) {animation = new Translateanimation (offset, one, 0, 0); 
    else if (Currindex = 2) {animation = new Translateanimation (two, one, 0, 0); 
   } break; 
    Case 2:if (Currindex = = 0) {animation = new Translateanimation (offset, two, 0, 0); 
    else if (Currindex = 1) {animation = new Translateanimation (one, two, 0, 0); 
   } break; 
   } currindex = arg0; 
   Animation.setfillafter (TRUE);/true: The picture stops at the animation end position Animation.setduration (300); 
  Cursor.startanimation (animation); @Override public void onpagescrolled (int arg0, float arg1, int arg2) {} @Override public void OnPage scrollstatechanged (int arg0) {}}/** * Viewpager adapter/public class Mypageradapter extends 
 
  {public list<view> mlistviews; Public Mypageradapter (list<view> mlistviews) {This.mlisTviews = Mlistviews; @Override public boolean isviewfromobject (View arg0, Object arg1) {//TODO auto-generated method stub R 
  Eturn arg0 = = arg1; 
  @Override public int GetCount () {//TODO auto-generated a stub return mlistviews.size ();  @Override public void Destroyitem (ViewGroup container, int position, object) {//TODO auto-generated 
  Method Stub Container.removeview (Mlistviews.get (position)); @Override public Object Instantiateitem (viewgroup container, int position) {//TODO auto-generated method s 
 
   Tub Container.addview (mlistviews.get (position)); 
  return Mlistviews.get (position); 

 } 
 } 
 
}

3. Focus Analysis
from easy to difficult step by step.
(1) initcursorpos ()---initialization indicator position
when the cursor is initialized, we want to display the cursor position based on the screen width. Let's take a look at this part of the code:

Initialize indicator position public 
void Initcursorpos () { 
 //Initialize animation 
 cursor = (imageview) Findviewbyid (r.id.cursor); 
 BMPW = Bitmapfactory.decoderesource (Getresources (), R.drawable.a) 
   . GetWidth ()//Get picture width 
 
 displaymetrics dm = New Displaymetrics (); 
 Getwindowmanager (). Getdefaultdisplay (). Getmetrics (DM); 
 int screenw = dm.widthpixels;//Get resolution width 
 offset = (screenw/viewlist.size ()-BMPW)/2;//compute offset 
 
 Matrix matrix = New Matrix (); 
 Matrix.posttranslate (offset, 0); 
 Cursor.setimagematrix (matrix);//Set animation initial position 
} 

Some students may not understand the position is that the initialization of the location of the offset why so counted, the following, I drew a picture, look at the next should understand.

Finally for the offset method, a lot of available, here The imitation of the Internet code with the matrix, of course, you can use the other offset method, the same.
(2) Mypagechangelistener ()---page change listener
the code is as follows:

public class Mypagechangelistener implements Onpagechangelistener {int one = offset * 2 + bmpw;//page card 1-> page Card 2 offset int two = one * 2;//page Card 1-> page Card 3 offset @Override public void onpageselected (int arg0) {Animation Animation = n 
  ull; 
   Switch (arg0) {case 0:if (currindex = = 1) {animation = new Translateanimation (one, 0, 0, 0); 
   else if (Currindex = = 2) {animation = new Translateanimation (two, 0, 0, 0); 
  } break; 
   Case 1:if (Currindex = = 0) {animation = new Translateanimation (offset, one, 0, 0); 
   else if (Currindex = 2) {animation = new Translateanimation (two, one, 0, 0); 
  } break; 
   Case 2:if (Currindex = = 0) {animation = new Translateanimation (offset, two, 0, 0); 
   else if (Currindex = 1) {animation = new Translateanimation (one, two, 0, 0); 
  } break; 
  } currindex = arg0; 
  Animation.setfillafter (TRUE);/true: The picture stops at the animation end position Animation.setduration (300); Cursor.startanimation (animation); 
 }

The principle is that, depending on the slide to the page, slide the cursor to the specified position.
There may be difficulty in this place, in mathematics ...
I drew a picture of why the distance from the first page to the second page was "cursor width +offset*2," and other distances were similar.

Using fragment to realize Viewpager sliding
Effect Chart:

Add a btn to the first page

The first page slides toward the second page

The second page slides towards the third page
Some notes:
Fragmentpageradapter is derived from Pageradapter, which is used to render fragment pages, which are kept in Fragment manager so that users can access them at any time.
This adapter is best used for limited static fragment page management. Although views that are not visible are sometimes destroyed, all fragment accessed by the user are saved in memory. So the fragment instance saves a large number of States, which creates a lot of memory overhead. So if you want to handle a lot of page transitions, it's recommended to use Fragmentstatepageradapter.
Every viewpager that uses fragmentpageradapter must have a valid set of IDs, and a collection of valid IDs is a collection of fragment (thanks to the prompts of the students)
For Fragmentpageradapter derived classes, it is only necessary to override the GetItem (int) and GetCount ().
Specific implementation:
1, adapter implementation--fragmentpageradapter
First look at the complete code, and then detail:

public class Fragadapter extends Fragmentpageradapter { 
 
 private list<fragment> mfragments; 
  
 Public Fragadapter (Fragmentmanager fm,list<fragment> fragments) { 
  super (FM); 
  TODO auto-generated constructor stub 
  mfragments=fragments; 
 } 
 
 @Override public 
 Fragment getitem (int arg0) { 
  //TODO auto-generated a stub return 
  mfragments.get ( arg0); 
 } 
 
 @Override public 
 int GetCount () { 
  //TODO auto-generated a stub return 
  mfragments.size (); 
 } 
 
} 

Here are three functions, according to the official document of the first part, that for fragmentpageradapter derived classes, only the getitem (int) and GetCount () can be overridden.
For constructors, a fragment list object is applied here to hold the fragment object for sliding and initialize it in the creation function:

Public Fragadapter (Fragmentmanager fm,list<fragment> fragments) { 
 super (FM); 
 TODO auto-generated constructor stub 
 mfragments=fragments; 
} 

Then, in GetItem (int arg0), the fragment that is currently being displayed is returned based on the arguments that came arg0.

Finally, GetCount () returns the total number of fragment used for sliding;

From the constructor, we can see that we are going to construct a set of fragment, so we first produce the fragment class we need;
2, three fragment class
First Fragment class:

XML: (Layout1.xml)

<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android= 
"http://schemas.android.com/apk/" Res/android " 
 android:layout_width=" match_parent " 
 android:layout_height=" Match_parent " 
 android: Background= "#ffffff" 
 android:orientation= "vertical" > 
  
 <button android:id= "@+id/fragment1_btn" 
  Android:layout_width= "Wrap_content" 
  android:layout_height= "wrap_content" 
  android:text= "show Toast" 
  /> 
</LinearLayout> 

In which a BTN was added

public class Fragment1 extends Fragment { 
  
 @Override public 
 View Oncreateview (layoutinflater inflater, ViewGroup Container, 
   Bundle savedinstancestate) { 
  //TODO auto-generated method stub 
  View view= Inflater.inflate ( R.LAYOUT.LAYOUT1, container, false); 
   
  Action method 
  Button btn = (button) View.findviewbyid for controls in view (R.ID.FRAGMENT1_BTN); 
  Btn.setonclicklistener (New View.onclicklistener () { 
    
   @Override public 
   void OnClick (View v) { 
    //TODO auto-generated method Stub 
    Toast.maketext (Getactivity (), "clicked the btn of the first fragment", Toast.length_short). Show (); 
  }); 
  return view; 
 } 
 

In Oncreateview () to return to display view, the above code simply demonstrates how to manipulate the control in the view, not difficult, no longer detailed, if the fragment not too familiar with the classmate, first look at this article: "Android fragment fully resolved, Everything you need to know about the pieces

Second Fragment class:

XML code: (layout2.xml) native code, without making any changes

<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android= 
"http://schemas.android.com/apk/" Res/android " 
 android:layout_width=" match_parent " 
 android:layout_height=" Match_parent " 
 android: Background= "#ffff00" 
 android:orientation= "vertical" > 
  
 
</LinearLayout> 
public class Fragment2 extends Fragment { 
  
 @Override public 
 View Oncreateview (Layoutinflater inflater, ViewGroup container, 
   Bundle savedinstancestate) { 
  //TODO auto-generated method stub 
  View view= Inflater.inflate (R.layout.layout2, container, false); 
  return view; 
 } 
 
 

A third fragment class:
XML code: (Layout3.xml) Same, native code, no changes made

<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android= 
"http://schemas.android.com/apk/" Res/android " 
 android:layout_width=" match_parent " 
 android:layout_height=" Match_parent " 
 android: Background= "#ff00ff" 
 android:orientation= "vertical" > 
  
 
</LinearLayout> 

Java code:

public class Fragment3 extends Fragment { 
  
 @Override public 
 View Oncreateview (Layoutinflater inflater, ViewGroup container, 
   Bundle savedinstancestate) { 
  //TODO auto-generated method stub 
  View view= Inflater.inflate (R.LAYOUT.LAYOUT3, container, false); 
  return view; 
 } 
 
 

3, the main activity to achieve
Core Code:

public class Mainactivity extends Fragmentactivity { 
 
 @Override 
 protected void OnCreate (Bundle Savedinstancestate) { 
  super.oncreate (savedinstancestate); 
  Setcontentview (r.layout.activity_main); 
 
  Construct Adapter 
  list<fragment> fragments=new arraylist<fragment> (); 
  Fragments.add (New Fragment1 ()); 
  Fragments.add (New Fragment2 ()); 
  Fragments.add (New Fragment3 ()); 
  Fragadapter adapter = new Fragadapter (Getsupportfragmentmanager (), fragments); 
   
  Set adapter 
  Viewpager VP = (viewpager) Findviewbyid (R.id.viewpager); 
  Vp.setadapter (adapter); 
 } 
 
 

First of all, there is a most noteworthy place: activity derived from fragmentactivity, in fact, this is the basic knowledge of fragment, only fragmentactivity can be embedded fragment page, ordinary activity is not.

This code is mainly divided into two steps, the first step: the construction of the adapter, the second step: set the adapter.
First look at the process of constructing the adapter:

Construct Adapter 
list<fragment> fragments=new arraylist<fragment> (); 
Fragments.add (New Fragment1 ()); 
Fragments.add (New Fragment2 ()); 
Fragments.add (New Fragment3 ()); 
Fragadapter adapter = new Fragadapter (Getsupportfragmentmanager (), fragments); 

Constructs a fragment list and then adds the corresponding instances of the three fragment classes above, and finally generates fragadapter instances.
As for the second step, set the adapter, there is nothing to talk about.

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.