自定义控件--->自定义菜单的实现和封装

来源:互联网 发布:java怎样配置环境变量 编辑:程序博客网 时间:2024/05/21 08:25

自定义控件—>自定义菜单的实现和封装

今天小编get了一个新的技能,就写了一个小demo实现自定义控还有对控件的封装,实现简化代码,提高可读性。那么现在就让我来介绍一下自定义菜单和封装方法。并附上源码。
源码下载:点击下载


首先创建一个项目MenuDemo

以下是项目的效果:
这里写图片描述

准备好各种菜单的图片资源

这里写图片描述

创建my_menu.xml文件

my_menu.xml文件用来提供已经摆放好的菜单图片,该xml文件是给继承了RelativeLayout的MenuView使用。代码如下所示:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <RelativeLayout        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:layout_centerHorizontal="true" >        <!-- 三级菜单 -->        <RelativeLayout             android:id="@+id/level3"            android:layout_width="280dp"            android:layout_height="140dp"            android:layout_alignParentBottom="true"            android:visibility="gone"            android:layout_alignParentLeft="true"            android:background="@drawable/level3" >            <!-- channel1 -->            <ImageView                android:id="@+id/level3_channel1"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_alignParentBottom="true"                android:layout_marginLeft="16dp"                android:src="@drawable/channel1" />            <!-- channel2 -->       <ImageView           android:id="@+id/level3_channel2"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_above="@id/level3_channel1"                android:layout_marginLeft="32dp"                android:layout_marginBottom="12dp"                android:src="@drawable/channel2" />       <!-- channel3 -->      <ImageView           android:id="@+id/level3_channel3"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_above="@id/level3_channel2"                android:layout_marginLeft="64dp"                android:layout_marginBottom="12dp"                android:src="@drawable/channel3" />      <!-- channel4 -->            <ImageView           android:id="@+id/level3_channel4"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_centerHorizontal="true"                android:layout_marginTop="8dp"                android:src="@drawable/channel4" />               <!-- channel7 -->            <ImageView                android:id="@+id/level3_channel7"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_alignParentBottom="true"                android:layout_alignParentRight="true"                android:layout_marginRight="16dp"                android:src="@drawable/channel7" />               <!-- channel1 -->            <!-- channel6 -->            <ImageView                android:id="@+id/level3_channel6"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_alignParentRight="true"                android:layout_marginRight="32dp"                android:layout_marginBottom="12dp"                android:layout_above="@id/level3_channel7"                android:src="@drawable/channel6" />                   <!-- channel5 -->      <ImageView           android:id="@+id/level3_channel5"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_above="@id/level3_channel2"                android:layout_marginRight="64dp"                android:layout_marginBottom="12dp"                android:layout_alignParentRight="true"                android:src="@drawable/channel5" />            </RelativeLayout>        <!-- 二级菜单 -->        <RelativeLayout            android:id="@+id/level2"            android:layout_width="180dp"            android:layout_height="90dp"            android:visibility="gone"            android:layout_alignParentBottom="true"            android:layout_centerHorizontal="true"            android:background="@drawable/level2" >            <!-- 搜索icon -->            <ImageView                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_alignParentBottom="true"                android:layout_marginLeft="5dp"                android:src="@drawable/icon_search" />            <!-- 优酷按钮 -->            <ImageView                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_alignParentBottom="true"                android:layout_alignParentRight="true"                android:layout_marginRight="5dp"                android:src="@drawable/icon_myyouku" />            <!-- 菜单按钮 -->            <ImageView                android:id="@+id/level2_menu"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_centerHorizontal="true"                android:layout_marginTop="5dp"                android:src="@drawable/icon_menu" />        </RelativeLayout>        <!-- 一级菜单 -->        <RelativeLayout            android:layout_width="100dp"            android:layout_height="50dp"            android:layout_alignParentBottom="true"            android:layout_centerHorizontal="true"            android:background="@drawable/level1" >            <!-- home图标 -->            <ImageView                android:id="@+id/level1_home"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_centerHorizontal="true"                android:layout_centerVertical="true"                android:src="@drawable/icon_home" />        </RelativeLayout>    </RelativeLayout></RelativeLayout>

定义一个继承RelativeLayout的MenuView类

该类主要是实现对xml文件的控件操作。代码如下:

package com.zqd.menudemo;import com.zqd.menudemo.MainActivity.MyAnimationListener;import com.zqd.youkumenudemo.R;import android.content.Context;import android.util.AttributeSet;import android.view.View;import android.view.View.OnClickListener;import android.view.animation.Animation;import android.view.animation.RotateAnimation;import android.view.animation.Animation.AnimationListener;import android.widget.ImageView;import android.widget.RelativeLayout;/** * @项目名: @YoukuMenuDemo * @包名:com.zqd.youkumenudemo * @类名:YoukuMenuView * @创建者:曾庆东 * @创建时间: 2016-1-26 下午11:06:08 * @描述: TODO *  */    public class MenuView extends RelativeLayout implements OnClickListener {        private ImageView mIvHome;         private ImageView mIvlmenu;         private boolean isLevel2Display=false;//设置二级菜单可见的状态        private boolean isLevel3Display=false;//设置三级菜单可见的状态        private RelativeLayout mcontainerLevel2;//二级菜单        private RelativeLayout mcontainerLevel3;//三级菜单        private int mCurrentAnimateCount;//当前有多少个动画正在执行        // 在View是new出来的时候使用    public MenuView(Context context) {        super(context);        initView();    }    // 在xml布局中使用    public MenuView(Context context, AttributeSet attrs) {        super(context, attrs);        initView();    }    private void initView() {        //给view关联xml,把view和xml进行绑定        View.inflate(getContext(), R.layout.youku_menu, this);        //设置相应activity中焦点事件        mIvHome=(ImageView) findViewById(R.id.level1_home);        mIvlmenu=(ImageView) findViewById(R.id.level2_menu);        mcontainerLevel2=(RelativeLayout) findViewById(R.id.level2);        mcontainerLevel3=(RelativeLayout) findViewById(R.id.level3);        //设置点击事件        mIvHome.setOnClickListener(this);        mIvlmenu.setOnClickListener(this);    }    @Override    public void onClick(View v) {        if(v==mIvHome){            //设置控件是可见的            mcontainerLevel2.setVisibility(View.VISIBLE);            clickLevel1Hmoe();        }        else if(v==mIvlmenu){            //设置控件是可见的            mcontainerLevel3.setVisibility(v.VISIBLE);            clickLevel2Menu();        }    }    // 点击二级菜单的menu按钮    private void clickLevel2Menu() {        //如果已经有view在做动画的情况下,就不去执行后面的代码                if(mCurrentAnimateCount>0){                    return;                }        //点击的是二级菜单的菜单按钮        //如果三级菜单可见,则隐藏三级菜单        if(isLevel3Display){        hiddenMenu(mcontainerLevel3, 0);        //改变标记        isLevel3Display=false;        /*return;*/        }        else{            //显示三级菜单            showMenu(mcontainerLevel3, 0);            isLevel3Display=true;        }        return;    }     // 1、点击home时    private void clickLevel1Hmoe() {        //如果已经有view在做动画的情况下,就不去执行后面的代码        if(mCurrentAnimateCount>0){            return;        }        //如果二级和三级菜单都不可见,显示二级菜单         if(!isLevel2Display&&!isLevel3Display){            showMenu(mcontainerLevel2,0);            isLevel2Display=true;            return; }        if(isLevel2Display&&isLevel3Display){             //如果二级菜单和三级菜单可见,那么就收起二级和三级菜单            //隐藏二级菜单和三级菜单        hiddenMenu(mcontainerLevel2,0);        hiddenMenu(mcontainerLevel3,100);        //改变标记        isLevel2Display=false;        isLevel3Display=false;        return;        }        //如果二级菜单显示,三级菜单不显示,那么隐藏二级菜单    if(isLevel2Display&&!isLevel3Display){            hiddenMenu(mcontainerLevel2,0);            isLevel2Display=false;            return;        }    }/*  private void clickHardMenu(){        if()    }    @Override    public boolean onKeyUp(int keyCode, KeyEvent event) {        // keyCode:指的是点击的硬件按钮的标记        if(keyCode==KeyEvent.KEYCODE_MENU){            System.out.println("点击了硬件的menu按钮");            clickHardMenu();            return true;        }        return super.onKeyUp(keyCode, event);    }*/    /**     * 隐藏     * @param container     *      * @prams     *     */    private void hiddenMenu(RelativeLayout container,int startOffset){    /*  container.setVisibility(View.GONE);*/        //设置菜单容器中所有的孩子都不可用,解决补间动画的触摸问题        int count=container.getChildCount();        for(int i=0;i<count;i++){            View view =container.getChildAt(i);            view.setEnabled(false);        }        //通过动画隐藏        RotateAnimation animation=new RotateAnimation(0,                                                    -180,                                                     RotateAnimation.RELATIVE_TO_SELF,                                                    0.5f,                                                     RotateAnimation.RELATIVE_TO_SELF,                                                     1f);        animation.setDuration(400);//设置时长        animation.setStartOffset(startOffset);//设置动画的延时        animation.setAnimationListener(new MyAnimationListener());//设置动画监听        animation.setFillAfter(true);//动画完成后,保持完成后的状态        container.startAnimation(animation);    }    /**     *      * @param container     *显示     * @prams     *     */    private void showMenu(RelativeLayout container,int startOffset){        /*container.setVisibility(View.VISIBLE);*/        //设置菜单容器中所有孩子可用        int count=container.getChildCount();        for(int i=0;i<count;i++){            View view =container.getChildAt(i);            view.setEnabled(true);        }        RotateAnimation rotate=new RotateAnimation(-180,//旋转的开始角度                                                    0,//旋转的结束角度                                                    RotateAnimation.RELATIVE_TO_SELF,//X轴的伸缩模式                                                    0.5f,//X坐标的伸缩值                                                    RotateAnimation.RELATIVE_TO_SELF, //Y轴的伸缩模式                                                    1f//Y坐标的伸缩值                                                    );        rotate.setDuration(400);//设置时长        rotate.setStartOffset(startOffset);//设置动画的延时        rotate.setFillAfter(true);//设置动画完成后保持原来的位置        container.startAnimation(rotate);//开启动画    }    class MyAnimationListener implements AnimationListener{        @Override        public void onAnimationEnd(Animation animation) {            mCurrentAnimateCount--;        }        @Override        public void onAnimationRepeat(Animation animation) {            // TODO Auto-generated method stub        }        @Override        public void onAnimationStart(Animation animation) {        mCurrentAnimateCount++;        }    }}

主界面的实现

在要实现主界面DemoActivity的xml中使用自定义的控件,注意,引用自定义控件的时候就要使用控件的实现类的全路径名,com.zqd.menudemo.MenuView。代码如下:

    <com.zqd.menudemo.MenuView        android:layout_alignParentBottom="true"        android:layout_centerHorizontal="true"        android:layout_width="wrap_content"        android:layout_height="wrap_content"     />

在DemoActivity中只需要使用setContentView(R.layout.activity_demo)使用该xml就可以和该xml关联起来。


好了,写博客的次数不是很多,不知道这样表达是否能让读者明白,如果写得不好的地方希望各位可以评论留言,你的评论是我不断更新的动力,希望这个demo可以帮助到各位想学安卓的童鞋,大家以后相互学习!!!

1 0
原创粉丝点击