如何通过AS实现单击式下拉菜单
2019-07-28 本文已影响0人
入梦瞌睡
1.需要实现的目标
-
通过点击按钮,实现下拉菜单的放出与收回
效果如图所示:
单击式下拉菜单.gif
2.实现该菜单所需要的思路
2.1 将素材导入到对应文件夹中
2.2 编写xml文件来改变app界面的外观
2.3 在.java文件中编写函数来实现xml中的响应事件
3.该菜单实现的具体步骤及其做法
3.1 将图片素材导入到对应文件夹中
图片类型的素材一般会导入到app文件夹下的res文件夹中的drawable文件夹或mipmap文件夹中
mipmap文件夹.JPG
3.2 通过编写xml文件来改变app界面的外观
3.2.1将图片素材放置到app界面中
打开res文件下的layout文件中的content_main.xml,该xml是用来设置app界面样式
xml位置.JPG
在xml文件中通过<ImageView/>标签可以将素材放置到app界面中
具体语法是:
<ImageView
android:src="@mipmap/b"/>
- 其中src=""引号中的为所引用图片的地址,@mipmap指的是选中该文件夹,后面的b表示图片的名称,写完该代码后,就已经把b.png导入到app界面上了
- 以此类推,
<ImageView
android:src="@mipmap/b"
/>
<ImageView
android:src="@mipmap/c"
/>
<ImageView
android:src="@mipmap/d"
/>
<ImageView
android:src="@mipmap/e"
/>
<ImageView
android:src="@mipmap/f"
/>
<ImageView
android:src="@mipmap/g"
/>
<ImageView
android:src="@mipmap/h"
/>
<ImageView
android:src="@mipmap/a"
/>
- 这样就可以把a到h的图片全部放到了app界面中
- 要注意的是,代码中处于下面的图片,会比处在上面的图片后导入,其结果就是后导入的图片会在先导入图片的上面那层
3.2.2 编辑导入到app界面中的图片
在<ImageView/>标签中添加
android:layout_width=""
android:layout_height=""
可以改变图片的长宽
android:layout_centerHorizontal="true"
可以使得图片水平居中
因此,我们可以将代码扩展为:
<ImageView
android:id="@+id/iv_b"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerHorizontal="true"
android:src="@mipmap/b"
android:layout_marginTop="5dp"
/>
<ImageView
android:id="@+id/iv_c"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerHorizontal="true"
android:src="@mipmap/c"
android:layout_marginTop="5dp"
/>
<ImageView
android:id="@+id/iv_d"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerHorizontal="true"
android:src="@mipmap/d"
android:layout_marginTop="5dp"
/>
<ImageView
android:id="@+id/iv_e"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerHorizontal="true"
android:src="@mipmap/e"
android:layout_marginTop="5dp"
/>
<ImageView
android:id="@+id/iv_f"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerHorizontal="true"
android:src="@mipmap/f"
android:layout_marginTop="5dp"
/>
<ImageView
android:id="@+id/iv_g"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerHorizontal="true"
android:src="@mipmap/g"
android:layout_marginTop="5dp"
/>
<ImageView
android:id="@+id/iv_h"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerHorizontal="true"
android:src="@mipmap/h"
android:layout_marginTop="5dp"
/>
<ImageView
android:id="@+id/iv_a"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_centerHorizontal="true"
android:onClick="ImgClick"
android:src="@mipmap/a"
/>
- 其中, android:id="@+id/iv_a",表示给该图片加一个id,类似于html语言中的id,可以靠id来选中对应的图片
- android:layout_marginTop="5dp"表示图片距离最上方5dp
- 最后一个标签中有 android:onClick="ImgClick",ImgClick是一个函数,在java文件中进行具体定义
- tips:在ImgClick还未定义的时候,光标选中它,按Alt+Enter可以快速创建函数
3.3 java文件中编写函数来实现xml中的响应事件
3.3.1在通过id找到xml文件中导入的各张图片
打开app文件中的java文件下的com.example.data1_meun_animation文件夹中的MainActivity.java
首先在MainActivity的class中添加:
private int[] resID = {R.id.iv_a,R.id.iv_b,R.id.iv_c,R.id.iv_d,R.id.iv_e,R.id.iv_f,R.id.iv_g,R.id.iv_h};
private List<ImageView> imageViews = new ArrayList<>();
private boolean isOpen = false;
- resID是一个数组,放的是各个图片的id(R是resource的简称)
- List数组放的是每一个图片本身
- isOpen是用来判断是否已经展开了菜单
然后再在onCreat函数中编写:
for(int i = 0 ; i<resID.length;i++){
int id = resID[i];
ImageView img = findViewById(id);
imageViews.add(img);
}
这个for循环,通过id将对应的图片放到名为imageViews的ArrayList中
3.3.2编写ImgClick函数
public void ImgClick(View view){
if(isOpen){
//收回列表
close();
}else{
//打开列表
open();
}
isOpen = !isOpen;
}
其中用open()函数来实现菜单展开,close()函数来实现菜单收回
private void close(){
for(int i=0;i<imageViews.size();i++)
{
ImageView iv = imageViews.get(i);
ObjectAnimator oa = ObjectAnimator.ofFloat(iv,"translationY",i*170f,0f);
oa.setDuration(1000);
oa.start();
}
}
private void open(){
for(int i=0;i<imageViews.size();i++)
{
ImageView iv = imageViews.get(i);
ObjectAnimator oa = ObjectAnimator.ofFloat(iv,"translationY",0f,i*170f);
oa.setDuration(1000);
oa.start();
oa.setInterpolator(new BounceInterpolator());
}
}
- ObjectAnimator.ofFloat(iv,"translationY",0f,i*170f);能定义Y轴方向的移动
- oa.setDuration(1000);能设置动画播放总时间
- oa.setInterpolator(new BounceInterpolator());能实现一个弹跳效果
4.应用拓展
同理可以实现多方向的展开
单击式扇形菜单.gif
具体只需要改变图片的位置,以及需要变更open()与close()的写法
private void close(){
double arc = 0;
for(int i=1;i<imageViews.size();i++){
ImageView iv = imageViews.get(i);
ObjectAnimator oa = ObjectAnimator.ofFloat(iv,"translationY",(float)Math.sin(arc)*250f,0f);
oa.setDuration(1000);
ObjectAnimator ob = ObjectAnimator.ofFloat(iv,"translationX",(float)Math.cos(arc)*250f,0f);
ob.setDuration(1000);
oa.start();
ob.start();
arc -= Math.toRadians(45);
}
}
private void open(){
double arc = 0;
for(int i=1;i<imageViews.size();i++){
ImageView iv = imageViews.get(i);
ObjectAnimator oa = ObjectAnimator.ofFloat(iv,"translationY",0f,(float)Math.sin(arc)*250f);
oa.setDuration(1000);
ObjectAnimator ob = ObjectAnimator.ofFloat(iv,"translationX",0f,(float)Math.cos(arc)*250f);
ob.setDuration(1000);
oa.start();
ob.start();
arc -= Math.toRadians(45);
}
}
- 其中Math.sin(arc)250f与Math.cos(arc)250f分别提供y轴方向的位移量与x轴方向的位移量
- arc -= Math.toRadians(45)意思为arc每次循环中减45度(用toRadians换算为弧度)