当前位置: 移动技术网 > IT编程>移动开发>Android > android效果TapBarMenu绘制底部导航栏的使用方式示例

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

2019年07月24日  | 移动技术网IT编程  | 我要评论

ca1625,大庆市公安局户籍科,陈墨镜

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

这里写图片描述      这里写图片描述

一、实现方式一:直接引入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>

这里写图片描述

在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请下载:

链接:

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网