Android custom control implements navigation bar that can slide left and right _android

Source: Internet
Author: User
Tags abs getcolor gety

First up Effect chart:

This control is actually relatively lightweight, I believe many small partners can do it. Because the project encountered a number of special customization requirements, so I wrote one, here put it out.
Let's first analyze the functionality of this control:
• Ability to respond to left and right slides and to respond to fast sliding
• There are different style expressions for selections and not selected items, such as foreground, background, and font size.
• Automatically scroll until the current option is fully exposed if the current option is not fully present in front of the interface when switching options
The first two also, simple to achieve, mainly the 3rd, this is the reason I customize this control! So what do you need to use to implement this control?
• Use Scroller to implement control scrolling
• Use Velocitytracker to enable fast scrolling of controls

If you already have both of these technologies, then we can start to explain the code. The first is the Getter/setter method of some attributes, the chain setting method used here:

 public Indicatorview Color (int colordefault, int colorselected, int colorbg) {
  this.colordefault = Colordefault;
  this.colorselected = colorselected;
  THIS.COLORBG = COLORBG;
  return this;
 }

 Public Indicatorview textsize (int textsize) {
  this.textsize = textsize;
  return this;
 }

 Public Indicatorview text (string[] texts) {
  this.texts = texts;
  return this;
 }

 Public Indicatorview padding (int[] padding) {
  this.padding = padding;
  return this;
 }

 Public Indicatorview defaultselect (int defaultselect) {
  this.selectitem = defaultselect;
  return this;
 }

 Public Indicatorview lineheight (int lineheight) {
  this.lineheight = lineheight;
  return this;
 }

 Public Indicatorview Listener (Onindicatorchangedlistener listener) {
  This.listener = listener;
  return this;
 }

 Public Indicatorview type (type type) {
  this.type = type;
  return this;
 }

Here we abstract each option into an item class:

 public class Item {
  String text;
  int colordefault;
  int colorselected;
  int textsize;
  Boolean isselected = false;
  int width;
  Point Drawpoint;
  int[] padding = new Int[4];
  Rect Rect = new Rect ();
 }

Then the initialization of the control, mainly based on the width of the current control, and some of the properties set, to initialize the item option:

 @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {width = measurespec.getsize (Widthmea
  SURESPEC);
  Height = measurespec.getsize (heightmeasurespec);
  Initialize item inititems ();
 Super.onmeasure (Widthmeasurespec, Heightmeasurespec);
  private void Inititems () {items.clear ();
  measurewidth = 0;
   for (int i = 0; i < texts.length i++) {item = new item ();
   Item.text = Texts[i];
   Item.colordefault = Colordefault;
   item.colorselected = colorselected;
   Item.textsize = Textsize;
   for (int j = 0; J < Item.padding.length; J +) {Item.padding[j] = padding[j];
   } mpaint.settextsize (Item.textsize);
   Item.width = (int) mpaint.measuretext (item.text);
   int dx = 0;
   if (I-1 < 0) {dx = 0; }else{for (int j = 0; J < i; j) {DX + items.get (j). Padding[0] + items.get (j). Width + items.get (j). padding[2
    ];
   int startx = item.padding[0] + dx;
  Paint.fontmetrics metrics = Mpaint.getfontmetrics (); int starty = (int) (HEIGHT/2 + (metrics.bottom-metrics.top)/2-metrics.bottom);
   Item.drawpoint = new Point (StartX, starty);
   Set the area Item.rect.left = item.drawpoint.x-item.padding[0];
   item.rect.top = 0;
   Item.rect.right = item.drawpoint.x + item.width + item.padding[2];
   Item.rect.bottom = height;
   Sets the default if (i = = SelectItem) {item.isselected = true;
   } Measurewidth + = Item.rect.width ();
  Items.Add (item);
 //Redraw invalidate ();

 }

  Next is event handling, and the logic is simple. Record the coordinate value in down time, handle the control's scrolling in move, the restore operation when the scrolling screen is processed in the up, and the clicked action. &NBSP

 @Override public boolean ontouchevent (Motionevent event) {if (Mvelocitytracker = null) {Mvelocitytracker = Veloci
  Tytracker.obtain ();
  } mvelocitytracker.addmovement (event);
    Switch (event.getaction ()) {Case MotionEvent.ACTION_DOWN:mTouchX = (int) event.getx ();
    Mtouchy = (int) event.gety ();
    Mmovex = Mtouchx;

   return true;
     Case MotionEvent.ACTION_MOVE:if (Measurewidth > width) {int dx = (int) event.getx ()-Mmovex; if (dx > 0) {//Right slip if (Mscroller.getfinalx () > 0) {mscroller.startscroll (), Mscroller.getfinalx (), Mscroller
      . Getfinaly (),-DX, 0);
      }else{mscroller.setfinalx (0); }}else{//Zoli if (mscroller.getfinalx () + WIDTH-DX < Measurewidth) {Mscroller.startscroll (Mscroller).
      Getfinalx (), Mscroller.getfinaly (),-DX, 0);
      }else{Mscroller.setfinalx (measurewidth-width);
     } Mmovex = (int) event.getx ();
    Invalidate ();

   } break; Case Motionevent.actiOn_up:case MotionEvent.ACTION_CANCEL:if (Measurewidth > width) {mvelocitytracker.computecurrentvelocity (10
     00);
     int max = Math.max (Math.Abs (Mscroller.getcurrx ()), Math.Abs (Measurewidth-width-mscroller.getcurrx ())); Mscroller.fling (Mscroller.getfinalx (), Mscroller.getfinaly (), (int)-mvelocitytracker.getxvelocity (), (int)-
     Mvelocitytracker.getyvelocity (), 0, Max, Mscroller.getfinaly (), mscroller.getfinaly ());
      When the finger is raised, initialize the position according to the scrolling offset if (Mscroller.getcurrx () < 0) {mscroller.abortanimation ();
     Mscroller.startscroll (Mscroller.getcurrx (), Mscroller.getcurry (),-mscroller.getcurrx (), 0);
      }else if (Mscroller.getcurrx () + width > measurewidth) {mscroller.abortanimation ();
     Mscroller.startscroll (Mscroller.getcurrx (), Mscroller.getcurry (), Measurewidth-width-mscroller.getcurrx (), 0);
     } if (event.getaction () = = motionevent.action_up) {int mupx = (int) event.getx ();
     int mupy = (int) event.gety (); Analog clicksAction if (Math.Abs (MUPX-MTOUCHX) <= mtouchslop && math.abs (mupy-mtouchy) <= mtouchslop) {for (int i = 0; I < items.size ();
        i++) {if (Items.get (i). Rect.contains (Mscroller.getcurrx () + MUPX, getscrolly () + mupy)) {setselected (i);
       Return Super.ontouchevent (event);

   Break in}}};
  Default:break;
 Return Super.ontouchevent (event);

 }

Next is a very important piece of code, because it allows you to automatically scroll to full display when the item option that is not fully displayed is selected:

 public void setselected (int position) {
  if (position >= items.size ()) {return
   ;
  }
  for (int i = 0; i < items.size (); i++) {
   if (i = = position) {
    items.get (i). IsSelected = true;
    if (i!= selectitem) {
     selectitem = i;
     Determine if it is necessary to slide to the fully visible
     if (Mscroller.getcurrx () + Width < Items.get (i). Rect.right) {
      Mscroller.startscroll ( Mscroller.getfinalx (), Mscroller.getfinaly (), Items.get (i). Rect.right-mscroller.getcurrx ()-width, Mscroller.getfinaly ());
     }
     if (Items.get (i). Rect.left < Mscroller.getcurrx ()) {
      mscroller.startscroll (Mscroller.getfinalx (), Mscroller.getfinaly (), Items.get (i). Rect.left-mscroller.getcurrx (), mscroller.getfinaly ());
     if (listener!= null) {
      listener.onchanged (SelectItem);}}}
   else{
    Items.get (i). isselected = false;
   }
  }
  Invalidate ();
 }

  Then is the drawing method, which is equivalent to the full agent giving the item to implement: &NBSP;

 @Override protected void OnDraw (Canvas Canvas) {Mpaint.setantialias (true);
  Canvas.drawcolor (COLORBG);
   for (Item item:items) {mpaint.settextsize (item.textsize);
     if (item.isselected) {if (type = = Type.selectbyline) {//Draw Red Line Mpaint.setcolor (item.colorselected);
     Mpaint.setstyle (Paint.Style.FILL); Canvas.drawroundrect (New RECTF (Item.rect.left, Item.rect.bottom-lineheight, Item.rect.right, Item.rect.bottom), 3, 3
    , Mpaint); }else if (type = = Type.selectbyfill) {//Draw red background mpaint.setcolor (GetContext (). Getresources (). GetColor (Android.
     R.color.holo_red_light));
     Mpaint.setstyle (Paint.Style.FILL); Canvas.drawroundrect (New RECTF (Item.rect.left + 6, item.rect.top, item.rect.right-6, Item.rect.bottom),
    Item.rect.height () * 5/12, Item.rect.height () * 5/12, Mpaint);
   } mpaint.setcolor (item.colorselected);
   }else{Mpaint.setcolor (Item.colordefault); } canvas.drawtext (Item.text, Item.drawpoint.x, Item.drawpoint.y, Mpaint);
 }
 }

The next step is how to use the control, the layout file:

 <?xml version= "1.0" encoding= "Utf-8"?> <relativelayout xmlns:android=
"http://schemas.android.com/apk" /res/android "
 android:id=" @+id/listview "
 android:layout_width=" match_parent "
 android:layout_height" = "Match_parent" >

 <cc.wxf.androiddemo.indicator.indicatorview
  android:id= "@+id/indicator"
  Android:layout_width= "Match_parent"
  android:layout_height= "38DP"/>
</RelativeLayout>

In mainactvity:

Package Cc.wxf.androiddemo;
Import Android.content.Context;
Import android.content.res.Resources;
Import Android.os.Bundle;

Import android.support.v4.app.FragmentActivity;

Import Cc.wxf.androiddemo.indicator.IndicatorView;

 public class Mainactivity extends Fragmentactivity {private Indicatorview indicatorview;
  @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
  Setcontentview (R.layout.activity_main);
 Initindicator ();
  private void Initindicator () {Indicatorview = (Indicatorview) Findviewbyid (r.id.indicator);
  Resources of resources = getresources (); Indicatorview.color (Resources.getcolor) (Android. R.color.black), Resources.getcolor (Android. R.color.holo_red_light), Resources.getcolor (Android. R.color.darker_gray)). Textsize (sp2px (this)). Padding (The new int[]{dip2px (this,), dip2px (this,), dip2px (thi S,), dip2px (This,)}). Text (New string[]{"TV series", "movie", "Comprehensive Art", "Flower", "anime", "Entertainment", "member 1", "Member 2", "Member 3", "Member 4", "member 5", "member 6"}). Defaultselect (0). Lineheight (Dip2px (this, 3)). Listener (New Indicatorview.onindicatorchangedlistene
 R () {@Override public void onchanged (int position) {}}). commit (); public static int dip2px (context context, float Dipvalue) {final float scale = context.getresources (). Getdisplaymetr
  ICS (). Density;
 return (int) (Dipvalue * scale + 0.5f); public static int sp2px (context context, float Spvalue) {final float scale = context.getresources (). getdisplaymetric
  S (). Scaleddensity;
 return (int) (Spvalue * scale + 0.5f);
  } @Override protected void OnDestroy () {Super.ondestroy ();
 Indicatorview.release ();


 }
}

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.

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.