Android实现下拉导航选择菜单效果(转)

本文转载自互联网

关于下拉导航选择菜单效果在新闻客户端中用的比较多,当然也可以用在其他的项目中,这样可以很方便的选择更多的菜单。我们可以让我们的应用顶部有左右滑动或进行切换的导航菜单,也可以为了增强用户体验在应用中添加这样的下拉导航选择菜单效果。

  关于它的实现原理,其实也是挺简单的,就是使用PopupWindow来进行展现,在显示时控制其高度并配置以相应的动画效果。在PopupWindow中我使用GridView来控制里面的菜单项,每个菜单项对应相应的图片和文字。当然了,也有其他的实现方式。为了大家能够清楚的理解,让我们先看下效果图,如下所示:

以上就是我实现的示例图,大家已经看到了,就是点击应用顶部中间的文字时展现出来,在我们点击其中一项菜单时隐藏并加载相应菜单的内容,同时该菜单处于选中状态。好了,下面就让我们开始我们的实现过程,还是先看下程序结构图吧:

在程序结构图中,PulldownMenuView是对PopupWindow进行的封装类,PulldownMenuItem是菜单项类,这是两个重要的类。在我们点击应用顶部中间的文字时,要进行展现,展现的同时,要实现对菜单的初始化工作,首先是初始化数据,其主要代码如下:

/**

* 初始化数据,将数据加载到对应的View中

*/

private void initData(){

PulldownMenuItem item = new PulldownMenuItem(context);

item.setMenuAlign(menuAlign);

item.setMenuTextColor(menuTextColor);

item.setMenuTextSize(menuTextSize);

int txtLength = menuTexts.length;

int imgLength = menuImageRes.length;

if (txtLength != 0 && imgLength != 0){

for (int i = 0; i < imgLength; i++){

PulldownMenuItem menuItem = new PulldownMenuItem(context, item);

if(!currentItem.equals(menuTexts[i])){

menuItem.setImageRes(menuImageRes[i]);

menuItem.setMenuText(menuTexts[i]);

}else{

menuItem.setMenuText(menuTexts[i]);

menuItem.setMenuTextColor(Color.parseColor("#4FA7F9"));

menuItem.setImageRes(ConstantCategoryMenu.newsImageResPress[i]);

}

menuMenuItems.add(menuItem);

}

} else{

if (txtLength != 0){

for (int i = 0; i < txtLength; i++){

PulldownMenuItem menuItem = new PulldownMenuItem(context, item);

if(!currentItem.equals(menuTexts[i])){

menuItem.setMenuText(menuTexts[i]);

}else{

menuItem.setMenuText(menuTexts[i]);

menuItem.setMenuTextColor(Color.parseColor("#4FA7F9"));

}

menuMenuItems.add(menuItem);

}

}else if (imgLength != 0){

for (int i = 0; i < imgLength; i++){

PulldownMenuItem menuItem = new PulldownMenuItem(context, item);

menuItem.setImageRes(menuImageRes[i]);

menuMenuItems.add(menuItem);

}

}

}

}

currentItem代表当前的选择项,在初始化数据过程中,需要检测哪项菜单被选中了,如果某项菜单被选中,则在展开时需要将该项菜单图片和文字颜色设置成相应状态,表示该项菜单被选中。在初始化过程中分为三种情况:第一种是菜单项既有图片也有文字;第二种是菜单项只有文字;第三种是菜单项只有图片;所以在上面代码中需要进行相应判断。上面是初始化菜单中的数据,下面是初始化菜单中的内容:

/**

* 初始化菜单内容

* @param context

* @param columns 菜单的列数

* @return

*/

private GridView getMenuGirdView(Context context, int columns){

if (menuMenuItems.isEmpty()){

// 初始化菜单数据

initData();

}

if (null != menuGridView){

return menuGridView;

}

GridView gridView = new GridView(context);

gridView.setLayoutParams(new LinearLayout.LayoutParams(

ViewGroup.LayoutParams.MATCH_PARENT,

ViewGroup.LayoutParams.MATCH_PARENT));

// 设置数据适配器

gridView.setAdapter(new PulldownMenuAdapter(menuMenuItems));

gridView.setVerticalSpacing(1);

gridView.setNumColumns(columns);

gridView.setGravity(Gravity.CENTER);

gridView.setVerticalScrollBarEnabled(false);

if (menuBackground != 0){

gridView.setBackgroundResource(menuBackground);

}

if (menuSelector != -1){

gridView.setSelector(menuSelector);

}

gridView.setHorizontalScrollBarEnabled(false);

setMenuListener(gridView);

return gridView;

}

初始化菜单之后,就需要我们菜单中相应的数据,设置数据比较容易,只需要三个数组即可:第一个数组代表菜单项文字内容;第二个数组代表菜单项图片资源,第三个数组代表菜单项被选中的图片资源。如下代码:

/**

* 新闻菜单项图片资源

*/

public final static int[] newsImageRes = {

R.drawable.ic_menu_toutiao,R.drawable.ic_menu_gn,

R.drawable.ic_menu_gj,R.drawable.ic_menu_sh,

R.drawable.ic_menu_sport,R.drawable.ic_menu_nba,

R.drawable.ic_menu_blog,R.drawable.ic_menu_book,

R.drawable.ic_menu_yule,R.drawable.ic_menu_mil,

R.drawable.ic_menu_cj,R.drawable.ic_menu_tech,

R.drawable.ic_menu_mobile,R.drawable.ic_menu_women,

R.drawable.ic_menu_car,R.drawable.ic_menu_house

};

/**

* 新闻菜单项选中图片资源

*/

public final static int[] newsImageResPress = {

R.drawable.ic_menu_toutiao_press,R.drawable.ic_menu_gn_press,

R.drawable.ic_menu_gj_press,R.drawable.ic_menu_sh_press,

R.drawable.ic_menu_sport_press,R.drawable.ic_menu_nba_press,

R.drawable.ic_menu_blog_press,R.drawable.ic_menu_book_press,

R.drawable.ic_menu_yule_press,R.drawable.ic_menu_mil_press,

R.drawable.ic_menu_cj_press,R.drawable.ic_menu_tech_press,

R.drawable.ic_menu_mobile_press,R.drawable.ic_menu_women_press,

R.drawable.ic_menu_car_press,R.drawable.ic_menu_house_press

};

/**

* 新闻菜单项文字

*/

public final static String[] newsMenuTexts = {

"今日头条","国内","国际","社会","体育","NBA","博客","读书",

"娱乐","军事","财经","科技","手机","女性","汽车","房产"

};

菜单项使用GridView实现,我们还需要设置每个菜单项的监听事件,在选中一项菜单后或是点击返回键或点击菜单键时实现隐藏,代码如下:

/**

* 设置菜单项监听事件

* @param gridView

*/

private void setMenuListener(GridView gridView){

if (null == gridView.getOnItemClickListener()){

gridView.setOnItemClickListener(new OnItemClickListener(){

@Override

public void onItemClick(

AdapterView<?> parent,

View view,

int position,

long id){

if (null != menuItemListener){

menuItemListener.onMenuItemClick(parent, view, position);

}

hide();

}

});

}

// 按返回键或菜单键隐藏菜单

gridView.setOnKeyListener(new OnKeyListener(){

@Override

public boolean onKey(View v, int keyCode, KeyEvent event){

if (event.getAction() == KeyEvent.ACTION_DOWN){

switch (keyCode){

case KeyEvent.KEYCODE_BACK:

case KeyEvent.KEYCODE_MENU:

hide();

break;

}

}

return false;

}

});

}

在PulldownMenuView类中的show()和hide()方法中,主要是实现菜单的显示与隐藏。在show()方法中,要计算每行存放的菜单数、设置相应的高度、菜单整体的背景、动画效果、菜单显示的位置等效果。具体不再详述。

  我们在显示下拉导航选择菜单前还需要配置菜单相应的参数,比如显示位置、背景图片、高度等。这就是在MenuUtility类中要实现的,代码如下:

package com.navigation.utility;

import com.navigation.acitvity.R;

import com.navigation.control.PulldownMenuView;

import android.content.Context;

import android.view.View;

/**

* PulldownMenuView基本操作类

* @Description: PulldownMenuView基本操作类

* @File: PulldownMenuUtility.java

* @Package com.navigation.utility

* @Author Hanyonglu

* @Date 2012-7-30 上午11:41:04

* @Version V1.0

*/

public class MenuUtility {

private Context context = null;

// PulldownMenuView对象

private PulldownMenuView menu = null;

// 图片资源

private int[] imageRes = null;

// 文字内容

private String[] texts = null;

// 菜单高度

private int height = 0;

private View anchorView = null;

/**

* 默认的构造器

*/

public MenuUtility() {

// TODO Auto-generated constructor stub

}

/**

* 带Context的构造器

* @param context

*/

public MenuUtility(Context context) {

// TODO Auto-generated constructor stub

this(context,null,null,0,null);

}

/**

* 带多参的构造器

* @param context

* @param imageRes

* @param texts

*/

public MenuUtility(Context context,int[] imageRes,String[] texts,int height,View anchorView){

this.context = context;

this.imageRes = imageRes;

this.texts = texts;

this.height = height;

this.anchorView = anchorView;

}

/**

* 设置图片资源

* @param imageRes

*/

public void setImageRes(int[] imageRes){

this.imageRes = imageRes;

}

/**

* 设置文字内容

* @param texts

*/

public void setTexts(String[] texts){

this.texts = texts;

}

/**

* 设置高度

* @param height

*/

public void setHeight(int height){

this.height = height;

}

/**

* 设置显示的位置

* @param anchor

*/

public void setAnchorView(View anchor){

anchorView = anchor;

}

/**

* 获取PulldownMenuView对象

* 以下拉的形式展现出来菜单

* @return

*/

public PulldownMenuView getPulldownMenuView(String currentItem){

PulldownMenuView menu = new PulldownMenuView(context);

menu.setImageRes(imageRes);

menu.setMenuText(texts);

menu.setHeight(height);

menu.setAnchorView(anchorView);

menu.setCurrentItem(currentItem);

menu.setBackground(R.drawable.navigation_bg);

return menu;

}

/**

* 获取PulldownMenuView对象

* 以向上弹出的方式展现出来菜单

* @return

*/

public PulldownMenuView getPopupMenuView(){

PulldownMenuView menu = new PulldownMenuView(context);

menu.setImageRes(imageRes);

menu.setMenuText(texts);

// menu.setLocation(Gravity.BOTTOM | Gravity.CENTER);

menu.setAnimStyle(R.style.pulldown_in_out);

menu.setBackground(R.drawable.navigation_bg);

return menu;

}

}

既然是使用PopupWindow实现我们的效果,当然了,它也可以以向上弹出的方式展现。在我这个示例中,需要它展现的位置是在顶部横条下面展现,所以设置:

menu.setAnchorView(anchorView);

另外,在MainActivity中需要设置它的显示高度,在这里高度需要在顶部横条和底部RadioGroup之间,这就需要我们获取手机屏幕的高度减去顶部横条的高度,再减去底部RadioGroup的高度,最后减去手机菜单栏的高度。在点击某项菜单后,还需要将顶部中间文字和右边三角图片进行相应的变换。代码如下所示:


package com.navigation.acitvity;



import com.navigation.constant.ConstantCategoryMenu;

import com.navigation.control.PulldownMenuView;

import com.navigation.control.PulldownMenuView.OnMenuItemClickListener;

import com.navigation.utility.DeviceUtility;

import com.navigation.utility.MenuUtility;



import android.app.Activity;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.AdapterView;

import android.widget.FrameLayout;

import android.widget.ImageView;

import android.widget.LinearLayout;

import android.widget.RelativeLayout;

import android.widget.TextView;



/**

 * Android实现下拉导航选择菜单效果

 * @Description: Android实现下拉导航选择菜单效果



 * @File: MainActivity.java



 * @Package com.navigation.acitvity



 * @Author Hanyonglu



 * @Date 2012-7-28 下午06:08:27



 * @Version V1.0

 */

public class MainActivity extends Activity {

    // 今日头条LinearLayout

    private LinearLayout linearLayoutTopic = null;

    // 界面布局

    private RelativeLayout layoutHeader = null;

    private LinearLayout layoutBottom = null;

    private FrameLayout layoutBody = null;

    // PulldownMenuView基本操作类

    private MenuUtility menuUtility = null;

    // PulldownMenuView对象

    private PulldownMenuView pullDownMenu = null;

    private TextView tvTopic = null;

    private ImageView ivTopic = null;

    

    private int height = 0;

    

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        

        // 初始化

        initViews();

    }

    

    /**

     * 初始化

     */

    protected void initViews(){    

        ivTopic = (ImageView) findViewById(R.id.imageViewTopic);

        tvTopic = (TextView) findViewById(R.id.textViewTopic);

        

        linearLayoutTopic = (LinearLayout)findViewById(R.id.linearLayoutTopic);

        linearLayoutTopic.setOnClickListener(TopicOnClickListener);

        layoutHeader = (RelativeLayout) findViewById(R.id.layout_top_header);

        layoutBottom = (LinearLayout) findViewById(R.id.layout_bottom);

        layoutBody = (FrameLayout) findViewById(R.id.layout_body);

        

        height = DeviceUtility.getScreenSize(this)[1] - 

                 layoutHeader.getLayoutParams().height - 

                   layoutBottom.getLayoutParams().height -

                   DeviceUtility.getStatusBarHeight(this);

        

        menuUtility = new MenuUtility(

                MainActivity.this, 

                ConstantCategoryMenu.newsImageRes,

                ConstantCategoryMenu.newsMenuTexts,

                height,layoutHeader);

    }

    

    /**

     * 显示PulldownMenuView

     */

    protected void showPulldownMenu(){

        pullDownMenu = menuUtility.getPulldownMenuView((String)tvTopic.getText());

        ivTopic.setImageResource(R.drawable.ic_menu_trangle_up);

    }

    

    /**

     * 隐藏PulldownMenuView

     */

    protected void hidePulldownMenu(){

        pullDownMenu.releasePopupMenuView();

        ivTopic.setImageResource(R.drawable.ic_menu_trangle_down);

    }

    

    // 顶部今日头条事件监听器

    private OnClickListener TopicOnClickListener = new OnClickListener() {

        @Override

        public void onClick(View v) {

            // 开始显示下拉菜单

            showPulldownMenu();

            

            // TODO Auto-generated method stub

            pullDownMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() {

                @Override

                public void onMenuItemClick(AdapterView<?> parent, View view, int position) {

                    // TODO Auto-generated method stub

                    tvTopic.setText(ConstantCategoryMenu.newsMenuTexts[position]);

                    layoutBody.setBackgroundResource(ConstantCategoryMenu.newsBodyRes[position]);

                }

                

                @Override

                public void hideMenu() {

                    // TODO Auto-generated method stub

                    hidePulldownMenu();

                }

            });

            

            pullDownMenu.show();

        }

    };

}





 我们在获取MainActivity中顶部横条和底部RadioGroup的高度时需要注意在布局文件中设置其相应的layout_height,否则,我们是获取不到其高度的。程序中间的主体部分是截取了几张图片,这个大家可以根据自己的需要设置成自己的数据格式。这点知道就可以了。

  以上便是Android中实现下拉导航选择菜单效果的实现过程,是在PopupWindow中嵌入GridView实现,当然也可以在PopupWindow中嵌入ListView等各种控件实现相应的效果,也可以对PopupWindow实现各种和样的变幻效果,具体过程这里就不再详述了,有兴趣的朋友我们可以一起探讨。

  源码下载地址:https://github.com/hanyonglu/MyPullDownMenu

				
时间: 2024-10-13 12:05:59

Android实现下拉导航选择菜单效果(转)的相关文章

Android实现下拉导航选择菜单效果【转载地址:http://www.cnblogs.com/hanyonglu/archive/2012/07/31/2617488.html】

本文介绍在Android中如何实现下拉导航选择菜单效果.   关于下拉导航选择菜单效果在新闻客户端中用的比较多,当然也可以用在其他的项目中,这样可以很方便的选择更多的菜单.我们可以让我们的应用顶部有左右滑动或进行切换的导航菜单,也可以为了增强用户体验在应用中添加这样的下拉导航选择菜单效果. 关于它的实现原理,其实也是挺简单的,就是使用PopupWindow来进行展现,在显示时控制其高度并配置以相应的动画效果.在PopupWindow中我使用GridView来控制里面的菜单项,每个菜单项对应相应的

通过html和css做出下拉导航栏的效果

引用前请标明出处:http://www.cnblogs.com/zkhzz/ 谢谢 通过观察了百度的首页,对于更多产品一栏,觉得可以不涉及JS便可写出下拉导航栏的效果 1.先设计出大体的框架 <div class="nav"> <ul> <li><a href="#">新闻</a></li> <li><a href="#">hao123</a&g

【Android UI设计与开发】第11期:顶部标题栏(二)ActionBar实现Tab选项卡和下拉导航列表

转载请注明出处:http://blog.csdn.net/yangyu20121224/article/details/9050573  在上一篇文章中,我们只是大概的了解了一下关于ActionBar这个类的简单用法,今天我会继续以实例进行更加深入的讲解. 一.实现Tab选项标签 当你想要在一个Activity中提供Tab选项卡时,使用ActionBar的Tab选项标签是一个非常好的选择(而不是使用TabWidget类),因为系统会调整ActionBar的选项标签来适应不同尺寸的屏幕的需要,比如

下拉框选择效果的实现原理

导航栏与下拉框的效果 实现的效果是在导航栏中间出现下拉框选择的效果,当选择某一个时,则上面的字也相应进行修改(此实例代码可以看Coding.net的源代码),这边有把它单独提取出来进行测试,源代码下载:接下来将简单介绍一下此实现的方式及主要代码: 1:因为我们是跟导航栏进行结合,所以这边用到的NavigationController,我们把这个页面的效果放在viewController中,弹出来的下拉列表这边是以表格的形式存在,每个则是表格的一行,行里面包括图标跟文字: 首先看一下AppDele

jquery实现的点击二级下拉导航菜单

jquery实现的点击二级下拉导航菜单:二级下拉导航菜单是各种类型的网站都有使用,所以是一个必须掌握的技能,对于老手来说肯定是轻松加愉快,但是对于初学者来说未必如此,下面就通过代码实例详细介绍一下点击二级下拉菜单实现过程.代码如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="htt

纯CSS实现的二级下拉导航菜单实例代码

纯CSS实现的二级下拉导航菜单实例代码:二级下拉菜单在众多的网站都有应用,不但能够有效的组织分类导航,并且能够节省大量的网站空间,也能够实现网站的动态化效果,大多数二级导航菜单都是结合javascript实现,本章节介绍一下使用纯css实现的下拉菜单.代码如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" co

20款jquery下拉导航菜单特效代码分享

jquery仿京东商城左侧分类导航下拉菜单代码 jQuery企业网站下拉导航菜单代码 jQuery css3黑色的多级导航菜单下拉列表代码 jquery响应式导航菜单支持手机导航菜单代码 jquery鼠标导航下滑显示图片列表效果 jQuery个性动画二级下拉导航代码 jquery网站下拉菜单制作企业网站导航菜单代码 jQuery游戏网站顶部滑动导航菜单代码 jquery.superfish.js导航菜单插件制作网页无限级下拉菜单代码 jquery hover事件实用的企业网站二级导航菜单样式 j

纯CSS实现二级下拉导航菜单

这是一款纯CSS菜单,二级下拉导航效果,是最简洁的CSS导航菜单,兼容性也很棒,IE7/8.火狐等都支持,而且它还是学习CSS菜单编写的典型教程,让你学会很多CSS技巧. 运行效果截图如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xm

MDNavBarView下拉导航菜单(仿美团导航下拉菜单)

说到下拉导航菜单这个东西用得还真不少,细心算一下做开发以来这样的菜单已经写了第三次了,但基本都是不能复用.感觉特累人.不经意看到同事写一个类似的下拉菜单,但他引用了开源库仿大众菜单的库,大致看了一下,感觉挺不错的,复用性也比较好,但要 是换成别的样式就要去修改代码了,感觉这有点不方便也比较容易出错.于是参照他的大致思路写了一个仿下拉菜单. 具体的实现就不多说了,觉得有意思的话可以下来看看.下面说一下使用方法吧: 1.添加navbarview包下的代码与对应资源 2.布局文件中添加: <com.m