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的位置就会错乱了
复制代码

 



本文转自农夫山泉别墅博客园博客,原文链接:http://www.cnblogs.com/yaowen/p/5003374.html,如需转载请自行联系原作者


相关文章
|
4月前
|
XML 搜索推荐 Android开发
Android改变进度条控件progressbar的样式(根据源码修改)
本文介绍了如何基于Android源码自定义ProgressBar样式。首先分析了系统源码中ProgressBar样式的定义,发现其依赖一张旋转图片实现动画效果。接着分两步指导开发者实现自定义:1) 模仿源码创建一个旋转动画XML文件(放置在drawable文件夹),修改图片为自定义样式;2) 在UI控件中通过`indeterminateDrawable`属性应用该动画。最终实现简单且个性化的ProgressBar效果,附带效果图展示。
253 2
|
4月前
|
Android开发
Android控件样式的抽取(小提及快捷方式)
在Android开发中,若多个控件样式重复,可抽取公共部分以简化代码。例如对EditText提取样式,通过编辑`styles.xml`实现复用。为提高效率,Android Studio提供自动提取Style功能:右键点击控件样式选项,选择“Style...”,勾选需要提取的属性后确认,即可快速生成样式代码,显著提升开发便利性。
124 2
|
11月前
|
缓存 搜索推荐 Android开发
安卓开发中的自定义控件实践
【10月更文挑战第4天】在安卓开发的海洋中,自定义控件是那片璀璨的星辰。它不仅让应用界面设计变得丰富多彩,还提升了用户体验。本文将带你探索自定义控件的核心概念、实现过程以及优化技巧,让你的应用在众多竞争者中脱颖而出。
|
9月前
|
搜索推荐 Android开发 开发者
安卓应用开发中的自定义控件实践
在安卓应用开发的广阔天地中,自定义控件如同璀璨的星辰,点亮了用户界面设计的夜空。它们不仅丰富了交互体验,更赋予了应用独特的个性。本文将带你领略自定义控件的魅力,从基础概念到实际应用,一步步揭示其背后的原理与技术细节。我们将通过一个简单的例子——打造一个具有独特动画效果的按钮,来展现自定义控件的强大功能和灵活性。无论你是初学者还是资深开发者,这篇文章都将为你打开一扇通往更高阶UI设计的大门。
109 2
|
11月前
|
缓存 搜索推荐 Android开发
安卓开发中的自定义控件基础与进阶
【10月更文挑战第5天】在Android应用开发中,自定义控件是提升用户体验和界面个性化的重要手段。本文将通过浅显易懂的语言和实例,引导你了解自定义控件的基本概念、创建流程以及高级应用技巧,帮助你在开发过程中更好地掌握自定义控件的使用和优化。
193 10
|
11月前
|
前端开发 搜索推荐 Android开发
安卓开发中的自定义控件实践
【10月更文挑战第4天】在安卓开发的世界里,自定义控件如同画家的画笔,能够绘制出独一无二的界面。通过掌握自定义控件的绘制技巧,开发者可以突破系统提供的界面元素限制,创造出既符合品牌形象又提供卓越用户体验的应用。本文将引导你了解自定义控件的核心概念,并通过一个简单的例子展示如何实现一个基本的自定义控件,让你的安卓应用在视觉和交互上与众不同。
|
10月前
|
前端开发 Android开发 UED
安卓应用开发中的自定义控件实践
【10月更文挑战第35天】在移动应用开发中,自定义控件是提升用户体验、增强界面表现力的重要手段。本文将通过一个安卓自定义控件的创建过程,展示如何从零开始构建一个具有交互功能的自定义视图。我们将探索关键概念和步骤,包括继承View类、处理测量与布局、绘制以及事件处理。最终,我们将实现一个简单的圆形进度条,并分析其性能优化。
|
12月前
|
缓存 前端开发 Android开发
安卓应用开发中的自定义控件
【9月更文挑战第28天】在安卓应用开发中,自定义控件是提升用户界面和交互体验的关键。本文通过介绍如何从零开始构建一个自定义控件,旨在帮助开发者理解并掌握自定义控件的创建过程。内容将涵盖设计思路、实现方法以及性能优化,确保开发者能够有效地集成或扩展现有控件功能,打造独特且高效的用户界面。
|
12月前
|
XML 编解码 Android开发
安卓开发中的自定义视图控件
【9月更文挑战第14天】在安卓开发中,自定义视图控件是一种高级技巧,它可以让开发者根据项目需求创建出独特的用户界面元素。本文将通过一个简单示例,引导你了解如何在安卓项目中实现自定义视图控件,包括创建自定义控件类、处理绘制逻辑以及响应用户交互。无论你是初学者还是有经验的开发者,这篇文章都会为你提供有价值的见解和技巧。
145 3
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义控件
【9月更文挑战第5天】在安卓开发的海洋中,自定义控件如同一艘精致的小船,让开发者能够乘风破浪,创造出既独特又高效的用户界面。本文将带你领略自定义控件的魅力,从基础概念到实战应用,一步步深入理解并掌握这一技术。