上一篇文章(https://blog.csdn.net/qq_36451275/article/details/95209106)主要讲解对自定义控件的基本的理解,这篇文章一优酷菜单为例简单的使用自定控件
一、优酷原型:
要做的效果:
二、分析实现的原理:
当我们去做一个效果的时候,要考虑是否有多种方案去实现。
如果有,就把所以的方案列举出来,并且用最简单或者你最熟悉的一种方式去实现该功能。
三、通过布局实现效果:
实现步骤
1_创建工程:01.优酷菜单
2_实现三个圆环-最里面的圆环
3_实现三个圆环-中间园环
4_实现三个圆环-最外环
5_最里环的的图标
6_中间环的图标
7_最外环的图标的左边部分
8_最外环的图标的右边部分
代码:
<RelativeLayout
android:id="@+id/level3"
android:layout_width="280dp"
android:layout_height="140dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/level3">
<ImageView
android:id="@+id/channel1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:src="@drawable/channel1" />
<ImageView
android:id="@+id/channel2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/channel1"
android:layout_marginBottom="8dp"
android:layout_marginLeft="33dp"
android:src="@drawable/channel2" />
<ImageView
android:id="@+id/channel3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/channel2"
android:layout_marginBottom="8dp"
android:layout_marginLeft="63dp"
android:src="@drawable/channel3" />
<ImageView
android:id="@+id/channel4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp"
android:src="@drawable/channel4" />
<ImageView
android:id="@+id/channel7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="8dp"
android:layout_marginRight="8dp"
android:src="@drawable/channel7" />
<ImageView
android:layout_alignParentRight="true"
android:id="@+id/channel6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/channel7"
android:layout_marginBottom="8dp"
android:layout_marginRight="33dp"
android:src="@drawable/channel6" />
<ImageView
android:layout_alignParentRight="true"
android:id="@+id/channel5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/channel6"
android:layout_marginBottom="8dp"
android:layout_marginRight="63dp"
android:src="@drawable/channel5" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/level2"
android:layout_width="180dp"
android:layout_height="90dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/level2">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:src="@drawable/icon_search" />
<ImageView
android:id="@+id/icon_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp"
android:src="@drawable/icon_menu" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="8dp"
android:layout_marginRight="8dp"
android:src="@drawable/icon_myyouku" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/level1"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/level1">
<ImageView
android:id="@+id/icon_home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/icon_home" />
</RelativeLayout>
四、代码逻辑处理:
代码实现步骤:
1_初始化三环的控件,并设置icon_menu和icon_menu的点击事件
2_三级菜单的显示和隐藏
3_二级菜单的显示和隐藏
4_设置延迟动画setStartOffset()方法和代码重构
5._监听手机menu按键实现菜单隐藏和显示
03_优酷效果的完成和bug修复-9
代码:
MainActivity.class类:
/**
* 是否显示第三圆环
* true:显示
* false隐藏
*/
private boolean isShowLevel3 = true;
/**
* 是否显示第二圆环
* true:显示
* false隐藏
*/
private boolean isShowLevel2 = true;
/**
* 是否显示第一圆环
* true:显示
* false隐藏
*/
private boolean isShowLevel1 = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
icon_home = (ImageView) findViewById(R.id.icon_home);
icon_menu = (ImageView) findViewById(R.id.icon_menu);
level1 = (RelativeLayout) findViewById(R.id.level1);
level2 = (RelativeLayout) findViewById(R.id.level2);
level3 = (RelativeLayout) findViewById(R.id.level3);
MyOnClickListener myOnClickListener = new MyOnClickListener();
//设置点击事件
icon_home.setOnClickListener(myOnClickListener);
icon_menu.setOnClickListener(myOnClickListener);
level1.setOnClickListener(myOnClickListener);
level2.setOnClickListener(myOnClickListener);
level3.setOnClickListener(myOnClickListener);
}
class MyOnClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.level1:
Toast.makeText(MainActivity.this, "level1", Toast.LENGTH_SHORT).show();
break;
case R.id.level2:
Toast.makeText(MainActivity.this, "level2", Toast.LENGTH_SHORT).show();
break;
case R.id.level3:
Toast.makeText(MainActivity.this, "level3", Toast.LENGTH_SHORT).show();
break;
case R.id.icon_home://home
//如果三级菜单和二级菜单是显示,都设置隐藏
if (isShowLevel2) {
//隐藏二级菜单
isShowLevel2 = false;
Tools.hideView(level2);
if (isShowLevel3) {
//隐藏三级菜单
isShowLevel3 = false;
Tools.hideView(level3, 200);
}
} else {
//如果都是隐藏的,二级菜单显示
//显示二级菜单
isShowLevel2 = true;
Tools.showView(level2);
}
break;
case R.id.icon_menu://菜单
if (isShowLevel3) {
//隐藏
isShowLevel3 = false;
Tools.hideView(level3);
} else {
//显示
isShowLevel3 = true;
Tools.showView(level3);
}
break;
}
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode ==KeyEvent.KEYCODE_MENU){
//如果一级,二级,三级菜单是显示的就全部隐藏
if(isShowLevel1){
isShowLevel1 = false;
Tools.hideView(level1);
if(isShowLevel2){
//隐藏二级菜单
isShowLevel2 = false;
Tools.hideView(level2,200);
if(isShowLevel3){
//隐藏三级菜单
isShowLevel3 = false;
Tools.hideView(level3,400);
}
}
}else{
//如果一级,二级菜单隐藏,就显示
//显示一级菜单
isShowLevel1 = true;
Tools.showView(level1);
//显示二级菜单
isShowLevel2 = true;
Tools.showView(level2,200);
}
return true;
}
return super.onKeyDown(keyCode, event);
}
所需要的工具类:
public class Tools {
public static void hideView(ViewGroup view) {
hideView(view, 0);
}
public static void showView(ViewGroup view) {
showView(view, 0);
}
public static void hideView(ViewGroup view, int 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);
// }
// //设置不可以点击
view.setEnabled(false);
//视图动画--属性动画
// view.setRotation();
ObjectAnimator animator = ObjectAnimator.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, int startOffset) {
// RotateAnimation ra = new RotateAnimation(180,360,view.getWidth()/2,view.getHeight());
// ra.setDuration(500);//设置动画播放持续的时间
// ra.setFillAfter(true);//动画停留在播放完成的状态
// ra.setStartOffset(startOffset);
// view.startAnimation(ra);
//
view.setEnabled(true);
// for(int i = 0;i<view.getChildCount();i++){
// View children = view.getChildAt(i);
// children.setEnabled(true);
// }
ObjectAnimator animator = ObjectAnimator.ofFloat(view,"rotation",180,360);
animator.setDuration(500);
animator.setStartDelay(startOffset);
animator.start();
view.setPivotX(view.getWidth() / 2);
view.setPivotY(view.getHeight());
}
}
五、动画的原理:
实验:
当菜单全部隐藏后,在icon_menu的位置点击一下看看效果。
动画的认识
View动画是对View的影像做操作,他并不能真正改变View的位置参数,包括宽和高,并且如果希望动画后的状态得以保留还必须将fillAfter属性设置为true,否则动画完成后其动画结果会消失。
解决方案
View和ViewGroup的初步认识
Android的UI界面都是由View和ViewGroup及其派生类组合而成的。
其中,View是所有UI组件的基类,而 ViewGroup是容纳这些组件的容器,其本身也是从View派生出来的.
View对象是Android平台中用户界面体现的基础单位。
View类是它称为“widgets(工具)”的子类的基础,它们提供了诸如文本输入框和按钮之类的UI对象的完整实现。
ViewGroup类同样为其被称为“Layouts(布局)”的子类奠定了基础,它们提供了象流式布局、表格布局以及相对布局之类的布局架构。
一般来说,开发Android应用程序的UI界面都不会直接使用View和ViewGroup,而是使用这两大基类的派生类。
View派生出的直接子类有:AnalogClock,ImageView,KeyboardView, ProgressBar,SurfaceView, TextView,ViewGroup,ViewStub
View派生出的间接子类有:AbsListView,AbsSeekBar, AbsSpinner, AbsoluteLayout, AdapterView,AdapterViewAnimator, AdapterViewFlipper, AppWidgetHostView, AutoCompleteTextView,Button,CalendarView, CheckBox, CheckedTextView, Chronometer, CompoundButton,
ViewGroup派生出的直接子类有:AbsoluteLayout,AdapterView,FragmentBreadCrumbs,FrameLayout, LinearLayout,RelativeLayout,SlidingDrawer
ViewGroup派生出的间接子类有:AbsListView,AbsSpinner, AdapterViewAnimator, AdapterViewFlipper, AppWidgetHostView, CalendarView, DatePicker, DialerFilter, ExpandableListView, Gallery, GestureOverlayView,GridView,HorizontalScrollView, ImageSwitcher,ListView,
这里特别指出,ImageView是布局具有图片效果的UI常用的类,SurfaceView是用来进行游戏开发的与一般View相比较为特殊的非常重要的类,而AbsoluteLayout、 FrameLayout,LinearLayout, RelativeLayout这几个ViewGroup的直接子类是Android UI布局中最基本的布局元素。