• android115 自定义控件


     

     布局:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
         >
    
        <!-- 一级菜单:最底下的圆形图片和房子的图片 -->
        <RelativeLayout android:layout_width="100dp"
            android:background="@drawable/level1"     最底下的圆形图片
            android:layout_alignParentBottom="true"   居于父窗体的底部
            android:id="@+id/level1"
            android:layout_centerHorizontal="true"    底部水平居中
            android:layout_height="50dp">
            
            <ImageView 
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"  水平和竖直居中
                android:id="@+id/iv_home"             房子的图片
                android:background="@drawable/icon_home"/>
            
        </RelativeLayout>
        
         <!-- 二级菜单:第二层的环形菜单 -->
        <RelativeLayout android:layout_width="180dp"
            android:layout_height="90dp"
            android:id="@+id/level2"
            android:layout_alignParentBottom="true"   居于父窗体的底部
            android:layout_centerHorizontal="true"    底部水平居中
            android:background="@drawable/level2">    第二层环形图片
            
            
                第二层环上的3个图片
            <ImageView android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_marginBottom="10dp"
                android:layout_marginLeft="10dp"
                android:background="@drawable/icon_search"/>   
            
             <ImageView android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_alignParentRight="true"
                android:layout_marginBottom="10dp"
                android:layout_marginRight="10dp"
                android:background="@drawable/icon_myyouku"/>
             
             <ImageView android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_marginTop="5dp"
                 android:id="@+id/iv_menu"
                 android:background="@drawable/icon_menu"
                 android:layout_centerHorizontal="true"/>
            
        </RelativeLayout>
        
            
        <RelativeLayout android:layout_width="280dp"
            android:layout_height="142dp"
            android:id="@+id/level3"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:background="@drawable/level3">    第三层环形图片
            
                第三层环上的7个图片
            <ImageView android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_marginBottom="15dp"
                android:layout_marginLeft="12dp"
                android:background="@drawable/channel1"
                />
            
            <ImageView android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_marginBottom="15dp"
                android:layout_alignParentRight="true"
                android:layout_marginRight="12dp"
                android:background="@drawable/channel5"
                />
            
             <ImageView android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_marginBottom="55dp"
                android:layout_marginLeft="32dp"
                android:background="@drawable/channel2"
                />
             
              <ImageView android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentBottom="true"
                    android:layout_alignParentRight="true"
                    android:layout_marginBottom="55dp"
                    android:layout_marginRight="32dp"
                    android:background="@drawable/channel6"
                />
              
                <ImageView android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentBottom="true"
                    android:layout_marginBottom="85dp"
                    android:layout_marginLeft="62dp"
                    android:background="@drawable/channel3"
                />
                
                 <ImageView android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true"
                    android:layout_alignParentBottom="true"
                    android:layout_marginBottom="85dp"
                    android:background="@drawable/channel7"
                    android:layout_marginRight="62dp"
                />
                 
                 <ImageView android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_marginTop="5dp"
                     android:layout_centerHorizontal="true"
                     android:background="@drawable/channel4"/>
            
        </RelativeLayout>
    </RelativeLayout>

    Activity:

    package com.heima52.youkumenu;
    
    import android.os.Bundle;
    import android.app.Activity;
    import android.util.Log;
    import android.view.KeyEvent;
    import android.view.Menu;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.ImageView;
    import android.widget.RelativeLayout;
    
    public class MainActivity extends Activity implements OnClickListener{
        private String tag = MainActivity.class.getSimpleName();
        private ImageView iv_home,iv_menu;
        private RelativeLayout level1,level2,level3;
        private boolean isShowLevel2 = true;//是否显示2级菜单
        private boolean isShowLevel3 = true;//是否显示3级菜单
        private boolean isShowMenu = true;//是否显示整个菜单,包括1级,2级,3级的菜单
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            initView();
            initListener();
        }
    
        private void initView() {
            setContentView(R.layout.activity_main);
            iv_home = (ImageView) findViewById(R.id.iv_home);//房子图片
            iv_menu = (ImageView) findViewById(R.id.iv_menu);
            level1 = (RelativeLayout) findViewById(R.id.level1);
            level2 = (RelativeLayout) findViewById(R.id.level2);
            level3 = (RelativeLayout) findViewById(R.id.level3);
        }
        
        private void initListener() {
            iv_home.setOnClickListener(this);//房子的点击事件
            iv_menu.setOnClickListener(this);//手机的菜单物理按键
        }
        
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            if(keyCode==KeyEvent.KEYCODE_MENU){//KEYCODE_MENU是常量82,
                /*
                public static final int KEYCODE_HEADSETHOOK     = 79;
                public static final int KEYCODE_FOCUS           = 80;   
                public static final int KEYCODE_PLUS            = 81;
                public static final int KEYCODE_MENU            = 82;
                public static final int KEYCODE_NOTIFICATION    = 83;
                public static final int KEYCODE_SEARCH          = 84;
                public static final int KEYCODE_MEDIA_PLAY_PAUSE= 85;
                public static final int KEYCODE_MEDIA_STOP      = 86;
                public static final int KEYCODE_MEDIA_NEXT      = 87;
                */
                if(isShowMenu){
                    //按手机菜单物理按键需要关闭所有菜单
                    int startOffset = 0;
                    if(isShowLevel3){//如果三级菜单是显示状态就隐藏,否则是隐藏就不执行。
                        AnimUtil.closeMenu(level3, startOffset);//关闭动画
                        isShowLevel3 = false;
                        startOffset += 200;
                    }
                    if(isShowLevel2){
                        AnimUtil.closeMenu(level2, startOffset);//关闭动画
                        isShowLevel2 = false;
                        startOffset += 200;
                    }
                    AnimUtil.closeMenu(level1, startOffset);//关闭动画
                }else {
                    //按手机菜单物理按键需要显示所有菜单
                    AnimUtil.showMenu(level1,0);//打开动画
                    AnimUtil.showMenu(level2,200);//打开动画
                    isShowLevel2 = true;
                    AnimUtil.showMenu(level3,400);//打开动画
                    isShowLevel3 = true;
                }
                isShowMenu = !isShowMenu;
                return true;//我们处理不让别的来处理
            }
            return super.onKeyDown(keyCode, event);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.iv_home:
                if(AnimUtil.animCount!=0){
                    //说明有动画正在执行,比如有动画正在关闭则不能在未完全关闭之前又执行打开。
                    return;
                }
                if(isShowLevel2){
                    //需要隐藏
                    int startOffset = 0;
                    if(isShowLevel3){
                        AnimUtil.closeMenu(level3,startOffset);
                        startOffset += 200;
                        isShowLevel3 = false;
                    }
                    AnimUtil.closeMenu(level2,startOffset);
                }else{
                    //需要显示
    //                Log.e(tag, "执行显示操作");
                    AnimUtil.showMenu(level2,0);
                }
                isShowLevel2 = !isShowLevel2;
                break;
            case R.id.iv_menu:
                if(AnimUtil.animCount!=0){
                    //说明有动画正在执行,比如有动画正在关闭则不能在未完全关闭之前又执行打开。
                    return;
                }
                if(isShowLevel3){
                    //隐藏3级菜单
                    AnimUtil.closeMenu(level3,0);
                }else {
                    //显示3级菜单
                    AnimUtil.showMenu(level3,0);
                }
                isShowLevel3 = !isShowLevel3;
                break;
            default:
                break;
            }
        }
    }

    工具:

    package com.heima52.youkumenu;
    
    import android.view.animation.Animation;
    import android.view.animation.Animation.AnimationListener;
    import android.view.animation.RotateAnimation;
    import android.widget.RelativeLayout;
    
    public class AnimUtil {
        public static int animCount = 0;//记录当前执行的动画数量
        
        //旋转动画的关闭
        public static void closeMenu(RelativeLayout rl,int startOffset){
            for (int i = 0; i < rl.getChildCount(); i++) {
                rl.getChildAt(i).setEnabled(false); //子view设为不可用,
                                                    //因为原生的旋转和位置动画并没有真正改变view的位置,
                                                    //View还在,也就是说在View消失后点击空白处还是点到了View上面,
                                                    //此时让view的enable属性置为false就不能点击了
            }
            //旋转动画
            RotateAnimation animation = new RotateAnimation(0, -180,//逆时针旋转,所以角度从0到-180
                    RotateAnimation.RELATIVE_TO_SELF, 0.5f,//旋转中心的X坐标是宽的一半处,
                    RotateAnimation.RELATIVE_TO_SELF, 1);//旋转中心的Y坐标是高度一倍处,
            animation.setDuration(500);//旋转时间是500毫秒
            animation.setFillAfter(true);//关闭动画结束后保持关闭的状态否则会又还原成显示状态。
            animation.setStartOffset(startOffset);//设置延时后执行
            animation.setAnimationListener(new MyAnimationListener());//设置Animation监听器
            rl.startAnimation(animation);
        }
        
        //旋转动画的打开
        public static void showMenu(RelativeLayout rl,int startOffset){
            for (int i = 0; i < rl.getChildCount(); i++) {
                rl.getChildAt(i).setEnabled(true);//子view设为可用,
            }
            RotateAnimation animation = new RotateAnimation(-180, 0,//从-180到0
                    RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                    RotateAnimation.RELATIVE_TO_SELF, 1);
            animation.setDuration(500);
            animation.setFillAfter(true);//打开动画结束后保持打开的状态,
            animation.setStartOffset(startOffset);
            animation.setAnimationListener(new MyAnimationListener());
            rl.startAnimation(animation);
        }
        
        static class MyAnimationListener implements AnimationListener{
            @Override
            public void onAnimationStart(Animation animation) {
                animCount++;
            }
            @Override
            public void onAnimationEnd(Animation animation) {
                animCount--;
            }
            @Override
            public void onAnimationRepeat(Animation animation) {
            }
            
        }
    }
    自定义控件:
        1.组合控件:将系统原生控件组合起来,加上动画效果,形成一种特殊的UI效果。
        2.纯粹自定义控件:继承自系统的View,自己去实现view效果。
    
    安卓中能够实现叠加的只有帧布局和相对布局,安卓中的view的边框都是矩形,没有圆形其他形状的。
    
    旋转动画:1,角度,逆时针旋转,    0—— -1802,旋转基于的点是自身最底部,
        
        
    优酷菜单:
        1.系统原生的旋转和位置动画并没有真正改变view的位置,View还在,也就是说在View消失后点击空白处还是点到了View上面,此时让view的enable属性置为false就不能点击了。如果是真正改变了位置那么其他相对布局的view的位置就会错乱了
  • 相关阅读:
    Android 高仿微信支付密码输入控件
    ListView用法总结
    我的感悟
    Android Scroll分析——滑动效果产生
    如何查看Android的Keystore文件的SHA1值
    Android 事件拦截机制一种粗鄙的解释
    Android 自定义ViewGroup
    Android 自定义View 总结
    Android 自定义View 三板斧之三——重写View来实现全新控件
    Android 自定义View 三板斧之二——组合现有控件
  • 原文地址:https://www.cnblogs.com/yaowen/p/5003374.html
Copyright © 2020-2023  润新知