常用控件回顾
- 按钮控件(Button和ImageButton)
ImageButton继承自ImageView,只显示图片;Button继承自TextView,用于显示文字。 - 进度条Progressbar
继承自View,显示正在运行的状态。有两种显示形式:环形和水平。通过style属性来改变样式。 - 单选按钮(RadioButton)和复选按钮(CheckBox)
都继承自CompoundButton,都只有选中和未选中两种状态,可以通过checked属性来设置。不同的是,在一个RadioGroup中只能有一个RadioButton处于选中状态,CheckBox则可以有多个按钮被选中。 - 状态开关按钮(ToggleButton)
继承自CompoundButton,状态只能是选中和未选中,并且需要为不同的状态设置不同的显示文本。 - 时钟控件(AnalogClock)和(DigitalClock)
AnalogClock继承自View,用于显示模拟时钟,只显示时针和分针;DigitalClock继承自TextView,用于显示数字时钟可精确到秒。
布局文件实现
- 效果展示
Android自定义View实现优酷菜单效果展示
2. activity_youkumenu.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/three"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_width="320dp"
android:layout_height="160dp"
android:background="@drawable/three">
<ImageView
android:id="@+id/img1"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/jiehuan"
android:tint="#ffffff"
android:layout_alignParentBottom="true"
android:layout_marginLeft="15dp"
android:layout_marginBottom="5dp"/>
<ImageView
android:id="@+id/img2"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/cheliangdangan"
android:tint="#ffffff"
android:layout_above="@id/img1"
android:layout_marginBottom="20dp"
android:layout_marginLeft="40dp"/>
<ImageView
android:id="@+id/img3"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/cheliangliebiao"
android:tint="#ffffff"
android:layout_above="@id/img2"
android:layout_marginBottom="20dp"
android:layout_marginLeft="80dp"/>
<ImageView
android:id="@+id/img4"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/cheliangxinxi"
android:tint="#ffffff"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"/>
<ImageView
android:id="@+id/img7"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/cheliangyiban"
android:tint="#ffffff"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="10dp"
android:layout_marginBottom="5dp"/>
<ImageView
android:id="@+id/img6"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/weixiu"
android:tint="#ffffff"
android:layout_above="@id/img7"
android:layout_marginBottom="20dp"
android:layout_marginRight="30dp"
android:layout_alignParentRight="true"/>
<ImageView
android:id="@+id/img5"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/zuche"
android:tint="#ffffff"
android:layout_above="@id/img6"
android:layout_marginBottom="20dp"
android:layout_marginRight="80dp"
android:layout_alignParentRight="true" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/two"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_width="220dp"
android:layout_height="110dp"
android:background="@drawable/two">
<ImageView
android:src="@drawable/baoyang"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="5dp"
android:layout_marginLeft="15dp"/>
<ImageView
android:id="@+id/menu"
android:src="@drawable/chakan"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"/>
<ImageView
android:src="@drawable/cheliang"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginRight="15dp"
android:layout_marginBottom="5dp"
android:layout_marginTop="20dp"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/one"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_width="120dp"
android:layout_height="60dp"
android:background="@drawable/one">
<ImageView
android:id="@+id/home"
android:src="@drawable/xinzeng"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="25dp"/>
</RelativeLayout>
</RelativeLayout>
- 效果图展示
代码处理逻辑
1.YouKuMenu.java
package com.swpuiot.test;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
public class YouKuMenu extends AppCompatActivity {
private ImageView home,menu;
private RelativeLayout one,two,three;
//是否显示第三个圆环
private boolean isShow3 = true;
//是否显示第二个圆环
private boolean isShow2 = true;
//是否显示第一个圆环
private boolean isShow1 = true;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_youkumenu);
initView();
//设置点击事件
MyOnclickListener myOnclickListener = new MyOnclickListener();
home.setOnClickListener(myOnclickListener);
menu.setOnClickListener(myOnclickListener);
}
class MyOnclickListener implements View.OnClickListener{
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.home:
//如果三级菜单和二级菜单是显示的,都设置隐藏
if(isShow2){
//隐藏二级菜单
isShow2 = false;
Tools.hideView(two,0);
if(isShow3){
//隐藏三级菜单
isShow3 = false;
Tools.hideView(three, 200);
}
}else {
//如果都是隐藏,显示二级菜单
isShow2 = true;
Tools.showView(two,0);
}
break;
case R.id.menu:
if(isShow3){
//隐藏
isShow3 = false;
Tools.hideView(three,0);
}else{
//显示
isShow3 = true;
Tools.showView(three,0);
}
break;
}
}
}
private void initView() {
home = findViewById(R.id.home);
menu = findViewById(R.id.menu);
one = findViewById(R.id.one);
two = findViewById(R.id.two);
three = findViewById(R.id.three);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_MENU){
//如果一级,二级,三级菜单是显示的,就全部隐藏
if(isShow1){
isShow1 = false;
Tools.hideView(one,0);
if(isShow2){
//隐藏二级菜单
isShow2 = false;
Tools.hideView(two,200);
if(isShow3){
//隐藏三级菜单
isShow3 = false;
Tools.hideView(three,400);
}
}
}else{
//如果一级,二级菜单隐藏,就显示
//显示一级菜单
isShow1 = true;
Tools.showView(one,0);
//显示二级菜单
isShow2 = true;
Tools.showView(two,200);
}
}
return super.onKeyDown(keyCode, event);
}
}
- Tools.java
package com.swpuiot.test;
import android.animation.ObjectAnimator;
import android.view.View;
import android.view.animation.RotateAnimation;
/**
* 显示和隐藏指定控件
*/
class Tools {
public static void hideView(View view, long startOffset) {
//方法一:视图动画
RotateAnimation ra = new RotateAnimation(0, 180, view.getWidth()/2, view.getHeight());
//设置动画播放持续的时间
ra.setDuration(500);
//动画停留在播放完成的状态
ra.setFillAfter(true);
//延迟多久后播放动画
ra.setStartOffset(startOffset);
view.startAnimation(ra);
}
public static void showView(View view, long startOffset) {
//方法一:视图动画
RotateAnimation ra = new RotateAnimation(180, 360, view.getWidth()/2, view.getHeight());
//设置动画播放持续的时间
ra.setDuration(500);
//动画停留在播放完成的状态
ra.setFillAfter(true);
ra.setStartOffset(startOffset);
view.startAnimation(ra);
}
}
}
解决bug的两种方法(ViewGroup和属性动画)
使用上面的Tools.java文件,我们会发现当点击物理按键menu时,一级、二级、三级菜单旋转180°隐藏之后点击隐藏掉的控件位置时仍然可以对控件进行操作,这是bug。
- 方法一:视图动画。使用ViewGroup,因为ViewGoup能够对子控件进行操作,而View则不能实现对子控件的操作。修改代码如下:
package com.swpuiot.test;
import android.animation.ObjectAnimator;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.RotateAnimation;
/**
* 显示和隐藏指定控件
*/
class Tools {
public static void hideView(ViewGroup view, long startOffset) {
//方法一:视图动画
RotateAnimation ra = new RotateAnimation(0, 180, view.getWidth()/2, view.getHeight());
//设置动画播放持续的时间
ra.setDuration(500);
//动画停留在播放完成的状态
ra.setFillAfter(true);
//延迟多久后播放动画
ra.setStartOffset(startOffset);
view.startAnimation(ra);
//设置不可点击
for (int i = 0; i < view.getChildCount(); i++) {
View children = view.getChildAt(i);
children.setEnabled(false);
}
}
public static void showView(ViewGroup view, long startOffset) {
//方法一:视图动画
RotateAnimation ra = new RotateAnimation(180, 360, view.getWidth()/2, view.getHeight());
//设置动画播放持续的时间
ra.setDuration(500);
//动画停留在播放完成的状态
ra.setFillAfter(true);
ra.setStartOffset(startOffset);
view.startAnimation(ra);
//设置可点击
for (int i = 0; i < view.getChildCount(); i++) {
View children = view.getChildAt(i);
children.setEnabled(true);
}
}
}
- 使用属性动画:
package com.swpuiot.test;
import android.animation.ObjectAnimator;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.RotateAnimation;
/**
* 显示和隐藏指定控件
*/
class Tools {
public static void hideView(ViewGroup view, long startOffset) {
//方法二:视图动画 --> 属性动画
ObjectAnimator animator = new ObjectAnimator();
animator.ofFloat(view,"rotation",0,180);
animator.setDuration(500);
animator.setStartDelay(startOffset);
animator.start();
view.setPivotX(view.getWidth()/2);
view.setPivotY(view.getHeight());
}
public static void showView(ViewGroup view, long startOffset) {
//方法二:视图动画 --> 属性动画
ObjectAnimator animator = new ObjectAnimator();
animator.ofFloat(view,"rotation",180,360);
animator.setDuration(500);
animator.setStartDelay(startOffset);
animator.start();
view.setPivotX(view.getWidth()/2);
view.setPivotY(view.getHeight());
}
}
说在最后面,在案例中所用到的图片均是在网上随意找的图片,所以大家可以自行准备一些图标进行试验。