Android realizes infinite loop effect of automatic wheel-seeding with indication point _android

Source: Internet
Author: User
Tags int size object object reflection static class time interval

To achieve infinite carousel, always slide to the left, when the last view, will slide to the first, infinite ...

Can write their own viewpager and then add handler first to achieve automatic scrolling, of course, here I for the progress of the project directly using the Trinea Android-auto-scroll-view-pager Library, URL: Click into the GitHub Reference library compile (' cn.trinea.android.view.autoscrollviewpager:android-auto-scroll-view-pager:1.1.2 ') {
Exclude module: After ' support-v4 '

1 layout for

<relativelayout 
android:layout_width= "match_parent" 
android:layout_height= "@dimen/y150" > 
<cn.trinea.android.view.autoscrollviewpager.autoscrollviewpager 
android:id= "@+id/viewpager1" 
Android:layout_width= "Match_parent" 
android:layout_height= "wrap_content"/> 
<!--dot layout--> 
<linearlayout 
android:id= "@+id/ll_dot1" 
android:layout_width= "match_parent" 
android:layout_ height= "Wrap_content" 
android:layout_alignparentbottom= "true" 
android:layout_marginbottom= "8DP" 
android:gravity= "center" 
android:orientation= "horizontal"/> 
</RelativeLayout> 

2 Building Pageradapter
Inherit from Recyclingpageradapter (the source code will be posted later)

 ' public class Indicator1adapter extends Recyclingpageradapter {private list<integer> imageidlist;
 Context context;

 Whether to loop (Create construct method, set whether in activity)//set size private int size;
  Public Indicator1adapter (list<integer> mdata) {this.imageidlist = Mdata;
  This.context = context;
  This.size = Mdata.size ();
 Isinfiniteloop = false; @Override public int GetCount () {//IS: Maximum (allow the length of the collection to simulate infinite loops) No, the collection length return Isinfiniteloop?
 Integer.MAX_VALUE:imageIdList.size ();
 }/** * @return the Isinfiniteloop */public boolean isinfiniteloop () {return isinfiniteloop; /** * @param is infinite loop/public Indicator1adapter Setinfiniteloop (Boolean isinfiniteloop) {This.isinfiniteloop =
  Isinfiniteloop;
 return this; /** * True Position * * @param position * @return * * private int getPosition (int position) {return Isinfin Iteloop?
 Position% Size:position; @Override public View getview (int position, view view, ViewGroup ContaiNER) {Viewholder holder;
   if (view = = null) {holder = new Viewholder ();
   view = Holder.imageview = new ImageView (context);
  View.settag (holder);
  else {holder = (Viewholder) view.gettag ();
  } holder.imageView.setImageResource (Imageidlist.get (getPosition (position)));
  Holder.imageView.setScaleType (ImageView.ScaleType.FIT_XY);
 return view;
 private static class Viewholder {ImageView ImageView;

 }
}

3 You can set up viewpager in an activity or in a fragment.

Defined member variables:

Viewpager1
 @BindView (r.id.viewpager1)
 Autoscrollviewpager mPager1;
 A control container that hosts a small point (there is a layout)
 @BindView (r.id.ll_dot1)
 linearlayout mLlDot1;
Indicator1adapter adapter1 = new Indicator1adapter (mdata,act). Setinfiniteloop (True);/Open infinite loop
  Mpager1.setadapter (adapter1);
  Mpager1.setinterval (play_time);//Carousel time interval
  mpager1.startautoscroll ();//Turn on automatic Carousel
  Mpager1.setcurrentitem ( INTEGER.MAX_VALUE/2-Integer.max_value/2% mdata.size ());

And then you don't want the official change. The time interval is too short to flash past, can be set by reflection

By reflection let the scrolling speed for its own liking (set here to 1.2s)
  try {
   Field field = ViewPager.class.getDeclaredField ("Mscroller");
   Field.setaccessible (true);
   Fixedspeedscroller scroller = new Fixedspeedscroller (Mpager1.getcontext (),
     new Accelerateinterpolator ());
   Field.set (MPager1, scroller);
   Scroller.setmduration (1200);
  } catch (Exception e) {
   log.e (TAG, "Exception", e);
  }

4 and then our little point hasn't been used yet.
Here I wrote the method:

/** * Set State point 1/private void setOvalLayout1 () {for (int i = 0; i < mdata.size (); i++) {/** * generates a corresponding number of dots (layouts,
  Results provided) */Mlldot1.addview (inflater.inflate (R.layout.dot, null));
  ///default display first page mlldot1.getchildat (0). Findviewbyid (R.id.v_dot). Setbackgroundresource (r.drawable.dot_selected); Mpager1.addonpagechangelistener (New Viewpager.onpagechangelistener () {public void onpageselected (int position) {/
    /traverse the image Array//Toast.maketext (Act, "position" +position, Toast.length_short). Show (); for (int i = 0; i < mdata.size (); i++) {if (I==position%mdata.size ()) {//dot selected/** * Here's to note if you write directly
      Position, because we are infinite loops, his position is infinitely upward * increase, then will report the null pointer, because we have generated a total of mdata.size () point, where we can let the current *position, get the current position of the point */Mlldot1.getchildat (Position%mdata.size ()). Findviewbyid (R.id.v_dot). Setbackgroundresource (R
     . drawable.dot_selected); }else{//Cancel dot Select Mlldot1.getchildat (curindex1%mdata.size ()). fIndviewbyid (R.id.v_dot). Setbackgroundresource (R.drawable.dot_normal);
   } curIndex1 = position;  public void onpagescrolled (int arg0, float arg1, int arg2) {} public void onpagescrollstatechanged (int arg0)


 {
   }
  });

 }

Don't forget to rewrite it.

 @Override public
 void OnPause () {
  super.onpause ();
  Stop Auto Scroll when OnPause
  mpager1.stopautoscroll ();
 }

 @Override public
 void Onresume () {
  super.onresume ();
  Start Auto Scroll when Onresume
  mpager1.startautoscroll ();
 }

OK, infinite loop automatic carousel, complete.

5 Point layout:

<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android"
 android:layout_width= "Wrap_ Content "
 android:layout_height=" wrap_content >
 <!--small dot View-->
 <view
  android:id = "@+id/v_dot"
  android:layout_width= "8DP"
  android:layout_height= "8DP"
  android:layout_marginleft= "2DP"
  android:layout_marginright= "2DP"
  android:background= "@drawable/dot_normal"/>
</ Relativelayout>

6 o ' background.
Dot_normal.xml

<?xml version= "1.0" encoding= "utf-8"?><!--dot is not selected--> <shape xmlns:android=
"http:// Schemas.android.com/apk/res/android "
 android:shape=" Oval ">
 <solid android:color=" @color Background_color "/>

 <corners android:radius=" 5DP "/>
</shape>

Dot_selected.xml

<?xml version= "1.0" encoding= "utf-8"?><!--dot selected--> <shape xmlns:android=
"http:// Schemas.android.com/apk/res/android "
 android:shape=" Oval ">
 <solid android:color=" @color/red " >
 <corners android:radius= "5DP"/>
</shape>

Recyclingpageradapter source code relies on the RecycleBin class, together posted out

The public class RecycleBin {/** * "* views", "were on screen" at the start of layout. This are populated at the "start of * layout," and at the "end of layout" All view in Activeviews are moved to Scrapview S. * View in Activeviews represent a contiguous range of views, with position of the the ' the ' the ' the ' of the
 Position.
 * Private view[] activeviews = new View[0];

 Private int[] Activeviewtypes = new Int[0]; /** unsorted views that can is used by the adapter as a convert view.

 * Private sparsearray<view>[] scrapviews;

 private int viewtypecount;

 Private sparsearray<view> currentscrapviews;  public void Setviewtypecount (int viewtypecount) {if (Viewtypecount < 1) {throw new IllegalArgumentException ("Can" t
 Have a Viewtypecount < 1 ");
 }//noinspection unchecked sparsearray<view>[] scrapviews = new Sparsearray[viewtypecount];
 for (int i = 0; i < Viewtypecount i++) {scrapviews[i] = new sparsearray<view> (); } This.viewTypecount = Viewtypecount;
 Currentscrapviews = Scrapviews[0];
 This.scrapviews = Scrapviews;
 } protected Boolean shouldrecycleviewtype (int viewtype) {return viewtype >= 0; /** @return A View from the Scrapviews collection. These are unordered. * * View getscrapview (int position, int viewtype) {if (Viewtypecount = = 1) {return Retrievefromscrap (Currentscrapview
 s, position);  else if (viewtype >= 0 && ViewType < scrapviews.length) {return retrievefromscrap (Scrapviews[viewtype),
 position);
 return null; /** * Put a view into the Scrapviews list.
 These views are unordered. * * @param scrap the view to add/void Addscrapview (view scrap, int position, int viewtype) {if (Viewtypecount = 1
 ) {Currentscrapviews.put (position, scrap);
 else {scrapviews[viewtype].put (position, scrap); } if (Build.VERSION.SDK_INT >= build.version_codes.
 Ice_cream_sandwich) {scrap.setaccessibilitydelegate (null); }/** Move all views remaininG in Activeviews to Scrapviews.
 * * void Scrapactiveviews () {final view[] activeviews = this.activeviews;
 Final int[] Activeviewtypes = this.activeviewtypes;

 Final Boolean multiplescraps = viewtypecount > 1;
 sparsearray<view> scrapviews = currentscrapviews;
 Final int count = Activeviews.length;
  for (int i = count-1 i >= 0; i--) {final View victim = activeviews[i];

  if (victim!= null) {int whichscrap = activeviewtypes[i];
  Activeviews[i] = null;

  Activeviewtypes[i] =-1;
  if (!shouldrecycleviewtype (Whichscrap)) {continue;
  } if (multiplescraps) {scrapviews = This.scrapviews[whichscrap];

  } scrapviews.put (I, victim); if (Build.VERSION.SDK_INT >= build.version_codes.
  Ice_cream_sandwich) {victim.setaccessibilitydelegate (null);
 }} prunescrapviews ();
 /** * Makes sure that this size of scrapviews does not exceed the size of activeviews.
 * (This can happen if a adapter does not recycle it views). * private void PRUnescrapviews () {final int maxviews = activeviews.length;
 Final int viewtypecount = This.viewtypecount;
 Final sparsearray<view>[] Scrapviews = this.scrapviews;
  for (int i = 0; i < Viewtypecount ++i) {final sparsearray<view> scrappile = scrapviews[i];
  int size = Scrappile.size ();
  final int extras = Size-maxviews;
  size--;
  for (int j = 0; j < Extras; J + +) {Scrappile.remove (Scrappile.keyat (size--)); 
 }} static View Retrievefromscrap (sparsearray<view> scrapviews, int position) {int size = Scrapviews.size ();
  if (Size > 0) {//If we still have a view for this position.
  for (int i = 0; i < size; i++) {int fromposition = Scrapviews.keyat (i);
  View view = Scrapviews.get (fromposition);
   if (fromposition = = position) {Scrapviews.remove (fromposition);
  return view;
  an int index = SIZE-1;
  View r = scrapviews.valueat (index);
  Scrapviews.remove (Scrapviews.keyat (index));
 return R;
 else {return null;}
 }
}

 

Recyclingpageradapter

Public abstract class Recyclingpageradapter extends Pageradapter {static final int ignore_item_view_type = Adapterview.

 Item_view_type_ignore;

 Private final RecycleBin RecycleBin;
 Public Recyclingpageradapter () {This (new RecycleBin ());
 } recyclingpageradapter (RecycleBin recyclebin) {this.recyclebin = RecycleBin;
 Recyclebin.setviewtypecount (Getviewtypecount ());
 @Override public void notifydatasetchanged () {recyclebin.scrapactiveviews ();
 Super.notifydatasetchanged (); @Override Public final Object instantiateitem (viewgroup container, int position) {int viewtype = Getitemviewtype (pos
 ition);
 View view = null;
 if (ViewType!= ignore_item_view_type) {VIEW = Recyclebin.getscrapview (position, viewtype);
 view = GetView (position, view, container);
 Container.addview (view);
 return view; @Override Public final void Destroyitem (ViewGroup container, int position, object) {View View object
 ;
 Container.removeview (view); int ViewType = GetItEmviewtype (position);
 if (ViewType!= ignore_item_view_type) {Recyclebin.addscrapview (VIEW, Position, ViewType);
 } @Override Public Final Boolean isviewfromobject (View view, Object object) {return view = = object; }/** * <p> * Returns The number of types of views that is created by * {@link #getView}. Each type represents a set of views that can is * converted in {@link #getView}.
 If the adapter always returns the same * type of View for all items, this method is should return 1. * </p> * <p> * This method to be called when the adapter is set on the * the {@link Adapterview
 }. * </p> * @return The number of types of views that would be created by this adapter/public int Getviewtypeco
 Unt () {return 1;
 }/** * Get the type of View this is created by {@link #getView} for the specified item.
 * * @param position the position of the item within the adapter ' s data set whose view type we * want. * @return an INteger representing the type of View. Two views should share the same type if one * can is converted to the other in {@link #getView}. Note:integers must is in the * range 0 to {@link #getViewTypeCount}-1.
 {@link #IGNORE_ITEM_VIEW_TYPE} can * also be returned.
 * @see #IGNORE_ITEM_VIEW_TYPE */@SuppressWarnings ("unusedparameters")//Argument potentially used by subclasses.
 public int Getitemviewtype (int position) {return 0; }/** * Get a View This displays the data at the specified position in the data set. can either * Create a View manually or inflate it from the XML layout file.
 When the view is inflated, the * parent View (GridView, ListView ...) 'll apply default layout parameters unless * {@link android.view.layoutinflater#inflate (int, ViewGroup, Boolean)} * To specify a root view and to prevent attachmen
 T to the root.
 * * @param position the position of the item within the adapter ' s data set of the item whose view * we want. * @param conVertview the old view to reuse, if possible. Note:you should check that this view * is non-null and of a appropriate type before using.
 If It isn't possible to convert * "This view" to "display" correct data, this method can create a new view. * Heterogeneous lists can specify their number of view types, so which is * always to the right type (view {@li
 NK #getViewTypeCount ()} and * {@link #getItemViewType (int)}).
 * @return A View corresponding to the ' data at the specified position.
* * Public abstract View getview (int position, view Convertview, ViewGroup container);
 }

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

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.