The Viewpager in Android realizes the sliding indicator and the matching with fragment _android

Source: Internet
Author: User
Tags stub

Self-implementing sliding indicator Bar
First up 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 "android:layout_height=" 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
Give all the code first and then explain it step-by-step.

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); 
 } 
 } 
 
}

From easy to difficult step by step.
1, Mypageradapter class

Generally our implementation of the adapter adapter is always new with a pageadapter instance. We made a little change here and set it up into a class with nothing changed, just one more constructor. So for the specific code of this class, I will no longer detail, if the function of the replication of which to write the students do not understand, please see "Viewpager detailed explanation (ii)---detailed four functions"

2. 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.

3, Mypagechangelistener ()---page change the 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.

This one is here, and the difficulty is not too much, it may not be too thin.
Source code, to everyone listed a tab interactive demo, the picture is as follows:

Using fragment to realize Viewpager sliding
using fragment to implement Viewpager sliding is an official recommendation of Android, so let's take a look at the 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

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), according to the parameters of the arg0, to return the current to display fragment, the following is the official explanation of GetItem, not very difficult, no longer detailed.
Public abstract Fragment GetItem (int position)

Return to the Fragment associated with a specified position.

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

Java code:

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; 
 } 
 

Returns the view to display in Oncreateview (), which is a simple demonstration of how to manipulate the controls in the view, not much more difficult. 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> 

Java code:

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.
4. Problems that may arise
Question: In mainactivity, when this sentence is written: Fragments.add (new Fragment1 ()); When you add an Fragement object instance to the fragment list, you are prompted "cannot convert Fragment1 () to Fragment"

Workaround: This is because the import package is inconsistent, and the general problem is that android.app.Fragment is imported into the Fragment1 and the class is imported here: Android.support.v4.app.Fragment, The package is different, of course, can not be converted, unified import as android.support.v4.app.Fragment after the normal

Related Article

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.