android效果TapBarMenu绘制底部导航栏的使用方式示例
程序员文章站
2024-02-20 11:59:40
其他的不多说了!我们来看看效果吧
一、实现方式一:直接引入compile方式
add the d...
其他的不多说了!我们来看看效果吧
一、实现方式一:直接引入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请下载:
链接:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。