欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

android效果TapBarMenu绘制底部导航栏的使用方式示例

程序员文章站 2024-02-20 11:59:40
其他的不多说了!我们来看看效果吧       一、实现方式一:直接引入compile方式 add the d...

其他的不多说了!我们来看看效果吧

android效果TapBarMenu绘制底部导航栏的使用方式示例      android效果TapBarMenu绘制底部导航栏的使用方式示例

一、实现方式一:直接引入compile方式

add the dependency to your build.gradle:

compile ‘com.github.michaldrabik:tapbarmenu:1.0.5'

布局设计

<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:background="@color/dark_gray"
 tools:context=".mainactivity">
 <!--中间按钮颜色-->
 <!--app:tbm_backgroundcolor="@color/red"-->

 <!--是否初始进入页面就可以看到item图片-->
 <!--app:tbm_showitems="true"-->

 <!--中间按钮大小-->
 <!--app:tbm_buttonsize="30dp"-->

 <!--中间按钮位置-->
 <!--app:tbm_buttonposition="center"-->

 <!--中间按钮位置左边距-->
 <!--app:tbm_buttonmarginleft="0dp"-->

 <!--中间按钮位置右边距-->
 <!--app:tbm_buttonmarginright="0dp"-->

 <!--中间按钮自定义图标打开状态。必须是一个向量可拉的动画。-->
 <!-- app:tbm_iconopened="@drawable/icon"-->

 <!--中间按钮自定义图标关闭状态。必须是一个向量可拉的动画。-->
 <!--app:tbm_iconopened="@drawable/icon"-->

 <!--中间按钮打卡item显示位置-->
 <!--app:tbm_menuanchor="bottom"-->
 <com.michaldrabik.tapbarmenulib.tapbarmenu
  android:id="@+id/tapbarmenu"
  android:layout_width="match_parent"
  android:layout_height="56dp"
  android:layout_alignparentbottom="true"
  android:layout_marginbottom="24dp"
  app:tbm_backgroundcolor="@color/red"
  app:tbm_buttonmarginleft="0dp"
  app:tbm_buttonmarginright="0dp"
  app:tbm_buttonposition="center"
  app:tbm_buttonsize="30dp"
  app:tbm_iconclosed="@drawable/icon"
  app:tbm_iconopened="@drawable/icon"
  app:tbm_menuanchor="bottom"
  app:tbm_showitems="false">

  <imageview
   android:id="@+id/item1"
   android:layout_width="0dp"
   android:layout_height="match_parent"
   android:layout_weight="1"
   android:paddingbottom="10dp"
   android:paddingtop="10dp"
   android:src="@drawable/ic_person"
   tools:visibility="visible" />

  <imageview
   android:id="@+id/item2"
   android:layout_width="0dp"
   android:layout_height="wrap_content"
   android:layout_weight="1"
   android:paddingbottom="10dp"
   android:paddingtop="10dp"
   android:src="@drawable/ic_location" />

  <space
   android:layout_width="0dp"
   android:layout_height="wrap_content"
   android:layout_weight="1" />

  <imageview
   android:id="@+id/item3"
   android:layout_width="0dp"
   android:layout_height="wrap_content"
   android:layout_weight="1"
   android:paddingbottom="10dp"
   android:paddingtop="10dp"
   android:src="@drawable/ic_thumb_up" />

  <imageview
   android:id="@+id/item4"
   android:layout_width="0dp"
   android:layout_height="wrap_content"
   android:layout_weight="1"
   android:paddingbottom="10dp"
   android:paddingtop="10dp"
   android:src="@drawable/ic_thumb_down" />

 </com.michaldrabik.tapbarmenulib.tapbarmenu>

 

</relativelayout>

android效果TapBarMenu绘制底部导航栏的使用方式示例

在activity中的代码

import android.os.bundle;
import android.support.v7.app.appcompatactivity;
import android.util.log;
import android.view.view;
import android.widget.toast;

import com.michaldrabik.tapbarmenulib.tapbarmenu;

import butterknife.bind;
import butterknife.butterknife;
import butterknife.onclick;

public class mainactivity extends appcompatactivity {

 @bind(r.id.tapbarmenu)
 tapbarmenu tapbarmenu;

 @override
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.activity_main);
  butterknife.bind(this);
 }

 private boolean isclick = true;

 @onclick(r.id.tapbarmenu)
 public void onmenubuttonclick() {
//  if (isclick) {
//   tapbarmenu.toggle();
//   isclick = false;
//  }
  tapbarmenu.toggle();
 }

 @onclick({r.id.item1, r.id.item2, r.id.item3, r.id.item4})
 public void onmenuitemclick(view view) {
// tapbarmenu.close();
  switch (view.getid()) {
   case r.id.item1:
    toast.maketext(this,"item1",toast.length_long).show();
    break;
   case r.id.item2:
    toast.maketext(this,"item2",toast.length_long).show();
    break;
   case r.id.item3:
    toast.maketext(this,"item3",toast.length_long).show();
    break;
   case r.id.item4:
    toast.maketext(this,"item4",toast.length_long).show();
    break;
  }
 }
}

到这里效果就基本实现了

二、实现方式二:引入module方式

module中记得引入

compile ‘com.wnafee:vector-compat:1.0.5'

import android.animation.animator;
import android.animation.animatorlisteneradapter;
import android.animation.animatorset;
import android.animation.valueanimator;
import android.annotation.targetapi;
import android.content.context;
import android.content.res.typedarray;
import android.graphics.canvas;
import android.graphics.paint;
import android.graphics.path;
import android.graphics.drawable.animatable;
import android.graphics.drawable.drawable;
import android.os.build;
import android.support.annotation.nonnull;
import android.support.v4.content.contextcompat;
import android.util.attributeset;
import android.view.gravity;
import android.view.motionevent;
import android.view.view;
import android.view.viewgroup;
import android.view.animation.decelerateinterpolator;
import android.widget.linearlayout;

import com.wnafee.vector.compat.resourcescompat;

/**
 * tapbar menu layout.
 *
 * @author michal drabik (michal.drabik0@gmail.com) on 2015-11-13.
 */
public class tapbarmenu extends linearlayout {

 public static final int button_position_left = 0;
 public static final int button_position_center = 1;
 public static final int button_position_right = 2;
 public static final int menu_anchor_bottom = 3;
 public static final int menu_anchor_top = 4;
 private static final decelerateinterpolator decelerate_interpolator = new decelerateinterpolator(2.5f);

 private enum state {
  opened,
  closed
 }

 private static final int left = 0;
 private static final int right = 1;
 private static final int top = 2;
 private static final int bottom = 3;
 private static final int radius = 4;

 private animatorset animatorset = new animatorset();
 private valueanimator[] animator = new valueanimator[5];
 private float[] button = new float[5];

 private path path = new path();
 private state state = state.closed;
 private paint paint;
 private int animationduration;
 private float width;
 private float height;
 private float buttonleftinitial;
 private float buttonrightinitial;
 private float yposition;
 private drawable iconopeneddrawable;
 private drawable iconcloseddrawable;
 private onclicklistener onclicklistener;

 //custom xml attributes
 private int backgroundcolor;
 private int buttonsize;
 private int buttonposition;
 private int buttonmarginright;
 private int buttonmarginleft;
 private int menuanchor;
 private boolean showmenuitems;

 public tapbarmenu(context context, attributeset attrs) {
  super(context, attrs);
  init(attrs);
 }

 public tapbarmenu(context context, attributeset attrs, int defstyleattr) {
  super(context, attrs, defstyleattr);
  init(attrs);
 }

 private void init(attributeset attrs) {
  setwillnotdraw(false);
  setupattributes(attrs);
  setgravity(gravity.center);
  setupanimators();
  setuppaint();
 }

 private void setupattributes(attributeset attrs) {
  typedarray typedarray = getcontext().obtainstyledattributes(attrs, r.styleable.tapbarmenu, 0, 0);

  if (typedarray.hasvalue(r.styleable.tapbarmenu_tbm_iconopened)) {
   iconopeneddrawable = typedarray.getdrawable(r.styleable.tapbarmenu_tbm_iconopened);
  } else {
   iconopeneddrawable = resourcescompat.getdrawable(getcontext(), r.drawable.icon_animated);
  }

  if (typedarray.hasvalue(r.styleable.tapbarmenu_tbm_iconclosed)) {
   iconcloseddrawable = typedarray.getdrawable(r.styleable.tapbarmenu_tbm_iconclosed);
  } else {
   iconcloseddrawable = resourcescompat.getdrawable(getcontext(), r.drawable.icon_close_animated);
  }

  backgroundcolor = typedarray.getcolor(r.styleable.tapbarmenu_tbm_backgroundcolor, contextcompat.getcolor(getcontext(), r.color.red));
  buttonsize =
    typedarray.getdimensionpixelsize(r.styleable.tapbarmenu_tbm_buttonsize, getresources().getdimensionpixelsize(r.dimen.defaultbuttonsize));
  buttonmarginright = typedarray.getdimensionpixelsize(r.styleable.tapbarmenu_tbm_buttonmarginright, 0);
  buttonmarginleft = typedarray.getdimensionpixelsize(r.styleable.tapbarmenu_tbm_buttonmarginleft, 0);
  buttonposition = typedarray.getint(r.styleable.tapbarmenu_tbm_buttonposition, button_position_center);
  menuanchor = typedarray.getint(r.styleable.tapbarmenu_tbm_menuanchor, menu_anchor_bottom);
  showmenuitems = typedarray.getboolean(r.styleable.tapbarmenu_tbm_showitems, false);
  typedarray.recycle();
 }

 private void setupanimators() {
  for (int i = 0; i < 5; i++) {
   animator[i] = new valueanimator();
  }

  animator[left].addupdatelistener(new valueanimator.animatorupdatelistener() {
   @override
   public void onanimationupdate(valueanimator valueanimator) {
    button[left] = (float) valueanimator.getanimatedvalue();
   }
  });
  animator[right].addupdatelistener(new valueanimator.animatorupdatelistener() {
   @override
   public void onanimationupdate(valueanimator valueanimator) {
    button[right] = (float) valueanimator.getanimatedvalue();
   }
  });
  animator[top].addupdatelistener(new valueanimator.animatorupdatelistener() {
   @override
   public void onanimationupdate(valueanimator valueanimator) {
    button[top] = (float) valueanimator.getanimatedvalue();
   }
  });
  animator[bottom].addupdatelistener(new valueanimator.animatorupdatelistener() {
   @override
   public void onanimationupdate(valueanimator valueanimator) {
    button[bottom] = (float) valueanimator.getanimatedvalue();
   }
  });
  animator[radius].addupdatelistener(new valueanimator.animatorupdatelistener() {
   @override
   public void onanimationupdate(valueanimator valueanimator) {
    button[radius] = (float) valueanimator.getanimatedvalue();
    invalidate();
   }
  });
  animationduration = getresources().getinteger(r.integer.animationduration);
  animatorset.setduration(animationduration);
  animatorset.setinterpolator(decelerate_interpolator);
  animatorset.playtogether(animator);
 }

 private void setupmenuitems() {
  for (int i = 0; i < getchildcount(); i++) {
   getchildat(i).setvisibility(showmenuitems ? visible : gone);
  }
 }

 private void setuppaint() {
  paint = new paint();
  paint.setcolor(backgroundcolor);
  paint.setantialias(true);
 }

 @override
 protected void onattachedtowindow() {
  super.onattachedtowindow();
  setupmenuitems();
 }

 /**
  * opens the menu if it's closed or close it if it's opened.
  */
 public void toggle() {
  if (state == state.opened)
   close();
  else
   open();
 }

 /**
  * open the menu.
  */
 public void open() {
  state = state.opened;
  showicons(true);

  animator[left].setfloatvalues(button[left], 0);
  animator[right].setfloatvalues(button[right], width);
  animator[radius].setfloatvalues(button[radius], 0);
  animator[top].setfloatvalues(button[top], 0);
  animator[bottom].setfloatvalues(button[bottom], height);

  animatorset.cancel();
  animatorset.start();
  if (iconopeneddrawable instanceof animatable) {
   ((animatable) iconopeneddrawable).start();
  }
  viewgroup parentview = (viewgroup) tapbarmenu.this.getparent();
  this.animate()
    .y(menuanchor == menu_anchor_bottom ? parentview.getbottom() - height : 0)
    .setduration(animationduration)
    .setinterpolator(decelerate_interpolator)
    .start();
 }

 /**
  * close the menu.
  */
 public void close() {
  updatedimensions(width, height);
  state = state.closed;
  showicons(false);

  animator[left].setfloatvalues(0, button[left]);
  animator[right].setfloatvalues(width, button[right]);
  animator[radius].setfloatvalues(0, button[radius]);
  animator[top].setfloatvalues(0, button[top]);
  animator[bottom].setfloatvalues(height, button[bottom]);

  animatorset.cancel();
  animatorset.start();
  if (iconcloseddrawable instanceof animatable) {
   ((animatable) iconcloseddrawable).start();
  }
  this.animate()
    .y(yposition)
    .setduration(animationduration)
    .setinterpolator(decelerate_interpolator)
    .start();
 }

 /**
  * @return true if menu is opened. false otherwise.
  */
 public boolean isopened() {
  return state == state.opened;
 }

 /**
  * sets tapbarmenu's background color from given resource.
  *
  * @param colorresid color resource id. for example: r.color.holo_blue_light
  */
 public void setmenubackgroundcolor(int colorresid) {
  backgroundcolor = contextcompat.getcolor(getcontext(), colorresid);
  paint.setcolor(backgroundcolor);
  invalidate();
 }

 /**
  * set position of 'open menu' button.
  *
  * @param position one of: {@link #button_position_center}, {@link #button_position_left}, {@link #button_position_right}.
  */
 public void setbuttonposition(int position) {
  buttonposition = position;
  invalidate();
 }

 /**
  * sets diameter of 'open menu' button.
  *
  * @param size diameter in pixels.
  */
 public void setbuttonsize(int size) {
  buttonsize = size;
  invalidate();
 }

 /**
  * sets left margin for 'open menu' button.
  *
  * @param margin left margin in pixels
  */
 public void setbuttonmarginleft(int margin) {
  buttonmarginleft = margin;
 }

 /**
  * sets right margin for 'open menu' button.
  *
  * @param margin right margin in pixels
  */
 public void setbuttonmarginright(int margin) {
  buttonmarginright = margin;
 }

 /**
  * set anchor point of the menu. can be either bottom or top.
  *
  * @param anchor one of: {@link #menu_anchor_bottom}, {@link #menu_anchor_top}.
  */
 public void setanchor(int anchor) {
  menuanchor = anchor;
 }

 /**
  * sets the passed drawable as the drawable to be used in the open state.
  *
  * @param opendrawable the open state drawable
  */
 public void seticonopendrawable(drawable opendrawable) {
  this.iconopeneddrawable = opendrawable;
  invalidate();
 }

 /**
  * sets the passed drawable as the drawable to be used in the closed state.
  *
  * @param closedrawable the closed state drawable
  */
 public void seticonclosedrawable(drawable closedrawable) {
  this.iconcloseddrawable = closedrawable;
  invalidate();
 }

 /**
  * sets the passed drawable as the drawable to be used in the open state.
  *
  * @param opendrawable the open state drawable
  */
 public void seticonopeneddrawable(drawable opendrawable) {
  this.iconopeneddrawable = opendrawable;
  invalidate();
 }

 /**
  * sets the passed drawable as the drawable to be used in the closed state.
  *
  * @param closedrawable the closed state drawable
  */
 public void seticoncloseddrawable(drawable closedrawable) {
  this.iconcloseddrawable = closedrawable;
  invalidate();
 }

 @override
 public void setonclicklistener(onclicklistener listener) {
  onclicklistener = listener;
 }

 @override
 protected void onsizechanged(int w, int h, int oldw, int oldh) {
  super.onsizechanged(w, h, oldw, oldh);
  updatedimensions(w, h);
  yposition = gety();
 }

 @override
 protected void ondraw(canvas canvas) {
  canvas.drawpath(createroundedrectpath(button[left], button[top], button[right], button[bottom], button[radius], button[radius], false), paint);
  if (state == state.closed) {
   iconcloseddrawable.draw(canvas);
  } else {
   iconopeneddrawable.draw(canvas);
  }
 }

 private void updatedimensions(float w, float h) {
  int ratio;
  width = w;
  height = h;

  button[radius] = buttonsize;
  setbuttonposition(width);
  if (iconcloseddrawable instanceof animatable) {
   ratio = 3;
  } else {
   ratio = 5;
  }
  float iconleft = button[left] + buttonsize / ratio;
  float icontop = (height - buttonsize) / 2 + buttonsize / ratio;

  float iconright = button[right] - buttonsize / ratio;
  float iconbottom = (height + buttonsize) / 2 - buttonsize / ratio;
  iconopeneddrawable.setbounds((int) iconleft, (int) icontop, (int) iconright, (int) iconbottom);
  iconcloseddrawable.setbounds((int) iconleft, (int) icontop, (int) iconright, (int) iconbottom);
 }

 private void setbuttonposition(float width) {
  if (buttonposition == button_position_center) {
   button[left] = ((width / 2) - (buttonsize / 2));
  } else if (buttonposition == button_position_left) {
   button[left] = 0;
  } else {
   button[left] = width - buttonsize;
  }
  int padding = buttonmarginleft - buttonmarginright;
  button[left] += padding;
  button[right] = button[left] + buttonsize;
  button[top] = (height - buttonsize) / 2;
  button[bottom] = (height + buttonsize) / 2;
  buttonleftinitial = button[left];
  buttonrightinitial = button[right];
 }

 private void showicons(final boolean show) {
  for (int i = 0; i < getchildcount(); i++) {
   final view view = getchildat(i);
   int translation = menuanchor == menu_anchor_bottom ? view.getheight() : -view.getheight();
   if (show){
    view.settranslationy(float.valueof(translation));
   }else {
    view.settranslationy(0f);
   }
//   view.settranslationy(show ? translation : 0f);
   view.setscalex(show ? 0f : 1f);
   view.setscaley(show ? 0f : 1f);
   view.setvisibility(visible);
   view.setalpha(show ? 0f : 1f);
   view.animate()
     .scalex(show ? 1f : 0f)
     .scaley(show ? 1f : 0f)
     .translationy(0f)
     .alpha(show ? 1f : 0f)
     .setinterpolator(decelerate_interpolator)
     .setduration(show ? animationduration / 2 : animationduration / 3)
     .setstartdelay(show ? animationduration / 3 : 0)
     .setlistener(new animatorlisteneradapter() {
      @override
      public void onanimationend(animator animation) {
       super.onanimationend(animation);
       view.setvisibility(show ? visible : gone);
      }
     })
     .start();
  }
 }

 private path createroundedrectpath(float left, float top, float right, float bottom, float rx, float ry, boolean conformtooriginalpost) {
  path.reset();
  if (build.version.sdk_int >= build.version_codes.lollipop) {
   return createroundedrectpathapi21(path, left, top, right, bottom, rx, ry, conformtooriginalpost);
  } else {
   return createroundedrectpathpreapi21(path, left, top, right, bottom, rx, ry, conformtooriginalpost);
  }
 }

 @targetapi(build.version_codes.lollipop)
 private path createroundedrectpathapi21(path path, float left, float top, float right, float bottom, float rx, float ry, boolean
   conformtooriginalpost) {
  if (rx < 0) rx = 0;
  if (ry < 0) ry = 0;
  float width = right - left;
  float height = bottom - top;
  if (rx > width / 2) rx = width / 2;
  if (ry > height / 2) ry = height / 2;
  float widthminuscorners = (width - (2 * rx));
  float heightminuscorners = (height - (2 * ry));
  path.moveto(right, top + ry);
  path.arcto(right - 2 * rx, top, right, top + 2 * ry, 0, -90, false);
  path.rlineto(-widthminuscorners, 0);
  path.arcto(left, top, left + 2 * rx, top + 2 * ry, 270, -90, false);
  path.rlineto(0, heightminuscorners);
  if (conformtooriginalpost) {
   path.rlineto(0, ry);
   path.rlineto(width, 0);
   path.rlineto(0, -ry);
  } else {
   path.arcto(left, bottom - 2 * ry, left + 2 * rx, bottom, 180, -90, false);
   path.rlineto(widthminuscorners, 0);
   path.arcto(right - 2 * rx, bottom - 2 * ry, right, bottom, 90, -90, false);
  }
  path.rlineto(0, -heightminuscorners);
  path.close();
  return path;
 }

 private path createroundedrectpathpreapi21(path path, float left, float top, float right, float bottom, float rx, float ry, boolean
   conformtooriginalpost) {
  if (rx < 0) rx = 0;
  if (ry < 0) ry = 0;
  float width = right - left;
  float height = bottom - top;
  if (rx > width / 2) rx = width / 2;
  if (ry > height / 2) ry = height / 2;
  float widthminuscorners = (width - (2 * rx));
  float heightminuscorners = (height - (2 * ry));
  path.moveto(right, top + ry);
  path.rquadto(0, -ry, -rx, -ry);
  path.rlineto(-widthminuscorners, 0);
  path.rquadto(-rx, 0, -rx, ry);
  path.rlineto(0, heightminuscorners);
  if (conformtooriginalpost) {
   path.rlineto(0, ry);
   path.rlineto(width, 0);
   path.rlineto(0, -ry);
  } else {
   path.rquadto(0, ry, rx, ry);
   path.rlineto(widthminuscorners, 0);
   path.rquadto(rx, 0, rx, -ry);
  }
  path.rlineto(0, -heightminuscorners);
  path.close();
  return path;
 }

 @override
 public boolean onintercepttouchevent(motionevent event) {
  return (event.getx() > buttonleftinitial && event.getx() < buttonrightinitial);
 }

 @override
 public boolean ontouchevent(@nonnull motionevent event) {
  if ((event.getx() > buttonleftinitial && event.getx() < buttonrightinitial) && (event.getaction() == motionevent.action_up)) {
   if (onclicklistener != null) {
    onclicklistener.onclick(this);
   }
  }
  return true;
 }

 @override
 protected void ondetachedfromwindow() {
  ondestroy();
  super.ondetachedfromwindow();
 }

 private void ondestroy() {
  iconopeneddrawable = null;
  iconcloseddrawable = null;
  for (int i = 0; i < 5; i++) {
   animator[i] = null;
  }
  animator = null;
  button = null;
  onclicklistener = null;
 }
}

布局和代码与上面一致,module请下载:

链接:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。