一莽鸿、彈出菜單
制作一個(gè)可以彈出的菜單,具體直接看效果吧~
具體實(shí)現(xiàn):
1拜轨,在XML文件里面添加圖片按鈕
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".MainActivity">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/id_d"
style="@style/ManuBtnStyle"
android:src="@drawable/d"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/id_c"
style="@style/ManuBtnStyle"
android:src="@drawable/c"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/id_b"
style="@style/ManuBtnStyle"
android:src="@drawable/b"
/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/id_a"
android:background="@null"
style="@style/ManuBtnStyle"
android:src="@drawable/a"/>
</RelativeLayout>
2抽减,為按鈕設(shè)置樣式,在values文件中
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="ManuBtnStyle">
<item name="android:background">@null</item>
<item name="android:layout_alignParentBottom">true</item>
<item name="android:layout_centerHorizontal">true</item>
</style>
</resources>
3橄碾,添加動(dòng)畫
(1)卵沉,定義數(shù)組保存所有的動(dòng)畫按鈕的資源ID
private int[] resld = {R.id.id_b,R.id.id_c,R.id.id_d};
(2),獲取菜單按鈕的狀態(tài)法牲,并為菜單按鈕添加點(diǎn)擊事件史汗,isOpen記錄按鈕菜單的是否是打開狀態(tài)
private void initView(){
//給菜單添加點(diǎn)擊事件
ImageButton menu = findViewById(R.id.id_a);
menu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//遍歷數(shù)組,取出每一個(gè)按鈕
for(int i = 0;i < resld.length;i++){
//判斷是打開 還是關(guān)閉
if(isOpen == true){
//之前是打開 拒垃,現(xiàn)在需要關(guān)閉
close(i);
}else{
//之間是關(guān)閉停撞,現(xiàn)在需要打開
open(i);
}
}
isOpen = !isOpen;
}
});
}
(3),定義方法封裝菜單的open和close動(dòng)畫
public void close(int i){
animate(i,true);
}
public void open(int i){
animate(i,false);
}
(4)悼瓮,實(shí)現(xiàn)動(dòng)畫戈毒,使用AnimationSet管理多個(gè)動(dòng)畫
public void animate(int i,boolean state){
//計(jì)算菜單平分之后的夾角
double angle = (Math.PI/(resld.length+1));
//獲取id對(duì)應(yīng)的控件
ImageButton imageButton = findViewById(resld[i]);
//計(jì)算當(dāng)前控制對(duì)應(yīng)控件的角度
double mAngle = (i+1) * angle;
//計(jì)算x距離
float x = (float)(Math.cos(mAngle) * 400);
//計(jì)算y距離
float y = (float)(Math.sin(mAngle) * 400);
float startx;
float tox;
float starty;
float toy;
Interpolator interpolator;
if(state == true){
startx = 0;
starty = 0;
tox = x;
toy = -y;
interpolator = new BounceInterpolator();
}else{
startx = x;
starty = -y;
tox = 0;
toy = 0;
interpolator = new AnticipateInterpolator();
}
//移動(dòng)的動(dòng)畫
TranslateAnimation translateAnimation = new TranslateAnimation(startx,tox,starty,toy);
translateAnimation.setDuration(500);
translateAnimation.setInterpolator(interpolator);
//旋轉(zhuǎn)的動(dòng)畫
RotateAnimation rotateAnimation = new RotateAnimation(0,360*3, Animation.RELATIVE_TO_SELF,
0.5f,Animation.RELATIVE_TO_SELF,0.5f);
rotateAnimation.setDuration(500);
//創(chuàng)建一個(gè)Animation集合 包裹多個(gè)動(dòng)畫
AnimationSet set = new AnimationSet(false);
set.setFillAfter(true); //保持狀態(tài)
set.addAnimation(rotateAnimation);
set.addAnimation(translateAnimation);
//開始動(dòng)畫
imageButton.startAnimation(set);
}
二、多級(jí)菜單
先展示效果:
具體實(shí)現(xiàn):
1横堡,在XML文件里面添加每層菜單的布局
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".MainActivity">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"/>
<!-- 一級(jí)菜單-->
<RelativeLayout
android:layout_width="100dp"
android:layout_height="50dp"
android:background="@drawable/level1"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true">
<ImageButton
android:id="@+id/ib_home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon_home"
android:background="@null"
android:layout_centerInParent="true"/>
</RelativeLayout>
<!-- 二級(jí)菜單-->
<RelativeLayout
android:id="@+id/rl_level2"
android:layout_width="200dp"
android:layout_height="100dp"
android:background="@drawable/level2"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
>
<ImageButton
android:id="@+id/ib_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon_menu"
android:background="@null"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dp"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon_search"
android:background="@null"
android:layout_alignParentBottom="true"
android:layout_marginLeft="150dp"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon_myyouku"
android:background="@null"
android:layout_alignParentBottom="true"
android:layout_marginRight="5dp"
/>
</RelativeLayout>
<!-- 三級(jí)菜單-->
<RelativeLayout
android:id="@+id/rl_level3"
android:layout_width="300dp"
android:layout_height="150dp"
android:background="@drawable/level3"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/channel1"
android:background="@null"
android:layout_marginLeft="5dp"
android:layout_alignParentBottom="true"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/channel7"
android:background="@null"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="5dp"
/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/channel2"
android:background="@null"
android:layout_marginLeft="25dp"
android:layout_marginTop="60dp"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/channel6"
android:background="@null"
android:layout_alignParentRight="true"
android:layout_marginRight="25dp"
android:layout_marginTop="60dp"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/channel3"
android:background="@null"
android:layout_marginLeft="60dp"
android:layout_marginTop="20dp"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/channel5"
android:background="@null"
android:layout_alignParentRight="true"
android:layout_marginRight="60dp"
android:layout_marginTop="20dp"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/channel4"
android:background="@null"
android:layout_centerHorizontal="true"
android:layout_marginTop="2dp"/>
</RelativeLayout>
</RelativeLayout>
效果圖:
2埋市,讀取XML文件里面的控件,并為菜單添加點(diǎn)擊事件
private boolean isOpen3 = true; //記錄三級(jí)菜單是否打開
private boolean isOpen2 = true; //記錄二級(jí)菜單是否打開
private RelativeLayout level3;
private RelativeLayout level2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//加載容器布局
level2 = findViewById(R.id.rl_level2);
level3 = findViewById(R.id.rl_level3);
ImageButton menu = findViewById(R.id.ib_menu);
ImageButton home = findViewById(R.id.ib_home);
//添加點(diǎn)擊事件
menu.setOnClickListener(this);
home.setOnClickListener(this);
3命贴,點(diǎn)擊二級(jí)菜單的菜單按鈕道宅,隱藏或顯示三級(jí)菜單
@Override
public void onClick(View v) {
//判斷哪一個(gè)菜單被點(diǎn)擊了
switch (v.getId()){
case R.id.ib_menu:
if(isOpen3){
//應(yīng)該關(guān)閉菜單
close(level3,200);
}else{
//應(yīng)該打開菜單
open(level3);
}
isOpen3 = !isOpen3;
break;
case R.id.ib_home:
if(isOpen3){
//如果顯示三級(jí)菜單,就關(guān)閉三級(jí)菜單
close(level3,0);
isOpen3 = false;
}
if(isOpen2){
//關(guān)閉二級(jí)菜單
close(level2,200);
}else{
//打開二級(jí)菜單
open(level2);
}
isOpen2 = !isOpen2;
break;
default:
break;
}
}
4套么,創(chuàng)建anim文件培己,然后添加動(dòng)畫
創(chuàng)建步驟:
創(chuàng)建完成后再回到Android項(xiàng)目,在src文件夾下就會(huì)出現(xiàn)anim動(dòng)畫文件胚泌,然后再在anim文件加下配置動(dòng)畫的XML文件
5,封裝旋轉(zhuǎn)動(dòng)畫
public void open(RelativeLayout relativeLayout){
//打開三級(jí)菜單
Animation in = AnimationUtils.loadAnimation(this,R.anim.rotate_in_anim);
relativeLayout.startAnimation(in);
//子控件可點(diǎn)擊
changeState(relativeLayout,true);
}
public void close(RelativeLayout relativeLayout,long dalay){
//關(guān)閉三級(jí)菜單
Animation out = AnimationUtils.loadAnimation(this,R.anim.rotate_out_anim);
out.setStartOffset(dalay); //添加延遲效果
relativeLayout.startAnimation(out);
//子控件不可點(diǎn)擊
changeState(relativeLayout,false);
}
其中解決了補(bǔ)間動(dòng)畫的弊端:視覺效果上翻轉(zhuǎn)上去了肃弟,點(diǎn)擊原來的位置玷室,按鈕還可以響應(yīng)事件。轉(zhuǎn)出去就設(shè)置這個(gè)容器的所有空間都可點(diǎn)擊笤受;轉(zhuǎn)回來的容器的所有子控件都可以點(diǎn)擊穷缤。
public void changeState(RelativeLayout relativeLayout,boolean enable){
//獲取容器子控件的個(gè)數(shù)
int childCount = relativeLayout.getChildCount();
//遍歷容器的子控件
for(int i =0;i < childCount;i++){
//取出對(duì)應(yīng)的子控件
View view = relativeLayout.getChildAt(i);
//設(shè)置子控件的狀態(tài)
view.setEnabled(enable);
}
}
MainActivity
完整代碼:
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private boolean isOpen3 = true; //記錄三級(jí)菜單是否打開
private boolean isOpen2 = true; //記錄二級(jí)菜單是否打開
private RelativeLayout level3;
private RelativeLayout level2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//加載容器布局
level2 = findViewById(R.id.rl_level2);
level3 = findViewById(R.id.rl_level3);
ImageButton menu = findViewById(R.id.ib_menu);
ImageButton home = findViewById(R.id.ib_home);
//添加點(diǎn)擊事件
menu.setOnClickListener(this);
home.setOnClickListener(this);
}
@Override
public void onClick(View v) {
//判斷哪一個(gè)菜單被點(diǎn)擊了
switch (v.getId()){
case R.id.ib_menu:
if(isOpen3){
//應(yīng)該關(guān)閉菜單
close(level3,200);
}else{
//應(yīng)該打開菜單
open(level3);
}
isOpen3 = !isOpen3;
break;
case R.id.ib_home:
if(isOpen3){
//如果顯示三級(jí)菜單,就關(guān)閉三級(jí)菜單
close(level3,0);
isOpen3 = false;
}
if(isOpen2){
//關(guān)閉二級(jí)菜單
close(level2,200);
}else{
//打開二級(jí)菜單
open(level2);
}
isOpen2 = !isOpen2;
break;
default:
break;
}
}
public void open(RelativeLayout relativeLayout){
//打開三級(jí)菜單
Animation in = AnimationUtils.loadAnimation(this,R.anim.rotate_in_anim);
relativeLayout.startAnimation(in);
//子控件可點(diǎn)擊
changeState(relativeLayout,true);
}
public void close(RelativeLayout relativeLayout,long dalay){
//關(guān)閉三級(jí)菜單
Animation out = AnimationUtils.loadAnimation(this,R.anim.rotate_out_anim);
out.setStartOffset(dalay);
relativeLayout.startAnimation(out);
//子控件不可點(diǎn)擊
changeState(relativeLayout,false);
}
public void changeState(RelativeLayout relativeLayout,boolean enable){
//獲取容器子控件的個(gè)數(shù)
int childCount = relativeLayout.getChildCount();
//遍歷容器的子控件
for(int i =0;i < childCount;i++){
//取出對(duì)應(yīng)的子控件
View view = relativeLayout.getChildAt(i);
//設(shè)置子控件的狀態(tài)
view.setEnabled(enable);
}
}
}
三箩兽、感悟
這個(gè)Demo雖然很簡單但寫起來的時(shí)候還是會(huì)出各種各樣的麻煩津肛,最難得地方就是動(dòng)畫旋轉(zhuǎn)角度,思維不縝密汗贫,還有待加強(qiáng)身坐。多多練習(xí)秸脱,熟能生巧!