Android仿今日头条APP实现下拉导航选择菜单效果

本文实例为大家分享了在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实现各种和样的变幻效果,具体过程这里就不再详述了,有兴趣的朋友我们可以一起探讨。
源码下载:下拉导航选择菜单

原文地址:http://www.cnblogs.com/hanyonglu/archive/2012/07/31/2617488.html

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android仿微信滑动弹出编辑、删除菜单效果、增加下拉刷新功能

    如何为不同的list item呈现不同的菜单,本文实例就为大家介绍了Android仿微信或QQ滑动弹出编辑.删除菜单效果.增加下拉刷新等功能的实现,分享给大家供大家参考,具体内容如下 效果图: 1. 下载开源项目,并将其中的liberary导入到自己的项目中: 2. 使用SwipeMenuListView代替ListView,在页面中布局: <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/swipeRefresh

  • Android编程实现仿优酷旋转菜单效果(附demo源码)

    本文实例讲述了Android编程实现仿优酷旋转菜单效果.分享给大家供大家参考,具体如下: 首先,看下效果: 不好意思,不会制作动态图片,只好上传静态的了,如果谁会,请教教我吧. 首先,看下xml文件: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" a

  • Android实现自定义滑动式抽屉效果菜单

    在Andoird使用Android自带的那些组件,像SlidingDrawer和DrawerLayout都是抽屉效果的菜单,但是在项目很多要实现的功能都收到Android这些自带组件的限制,导致很难完成项目的需求,自定义的组件,各方面都在自己的控制之下,从而根据需求做出调整.想要实现好的效果,基本上都的基于Android的OnTouch事件自己实现响应的功能. 首先,给大家先看一下整体的效果: 滑动的加速度效果都是有的,具体的体验,只能安装后才能查看. 接下来,看代码: 代码从MainActiv

  • Android App中DrawerLayout抽屉效果的菜单编写实例

    抽屉效果的导航菜单 看了很多应用,觉得这种侧滑的抽屉效果的菜单很好. 不用切换到另一个页面,也不用去按菜单的硬件按钮,直接在界面上一个按钮点击,菜单就滑出来,而且感觉能放很多东西. 库的引用: 首先, DrawerLayout这个类是在Support Library里的,需要加上android-support-v4.jar这个包. 然后程序中用时在前面导入import android.support.v4.widget.DrawerLayout; 如果找不到这个类,首先用SDK Manager更

  • Android编程实现仿优酷圆盘旋转菜单效果的方法详解【附demo源码下载】

    本文实例讲述了Android编程实现仿优酷圆盘旋转菜单效果的方法.分享给大家供大家参考,具体如下: 目前,用户对安卓应用程序的UI设计要求越来越高,因此,掌握一些新颖的设计很有必要. 比如菜单,传统的菜单已经不能满足用户的需求. 其中优酷中圆盘旋转菜单的实现就比较优秀,这里我提供下我的思路及实现,仅供参考. 该菜单共分里外三层导航菜单.可以依次从外向里关闭三层菜单,也可以反向打开,并且伴有圆盘旋转的动画效果 首先,看下效果: 以下是具体的代码及解释: 1. 菜单布局文件: 大家看到主要有三个Ra

  • Android编程实现仿美团或淘宝的多级分类菜单效果示例【附demo源码下载】

    本文实例讲述了Android编程实现仿美团或淘宝的多级分类菜单效果.分享给大家供大家参考,具体如下: 这里要实现的是诸如美团/淘宝/百度糯米 多级分类菜单效果.当分类数量非常多时可以考虑采用两级分类,而诸如美团这种表现方式是一个不错的选择. 首先上效果图:   主要代码: 1. PopupWindow初始化过程: popupWindow = new PopupWindow(this); View view = LayoutInflater.from(this).inflate(R.layout.

  • Android自定义控件之仿优酷菜单

    去年的优酷HD版有过这样一种菜单,如下图: 应用打开之后,先是三个弧形的三级菜单,点击实体键menu之后,这三个菜单依次旋转退出,再点击实体键menu之后,一级菜单会旋转进入,点击一级菜单,二级菜单旋转进入,点击二级菜单的menu键,三级菜单旋转进入,再次点击二级菜单的旋转键,三级菜单又会旋转退出,这时再点击一级菜单,二级菜单退出,最后点击实体menu键,一级菜单退出. 总体来说实现这样的功能: (1)点击实体menu键时,如果界面上有菜单显示,不管有几个,全部依次退出,如果界面上没有菜单显示,

  • Android实现顶部导航菜单左右滑动效果

    本文给大家介绍在Android中如何实现顶部导航菜单左右滑动效果,具体内容如下 第一种解决方案: 实现原理是使用android-support-v4.jar包中ViewPager控件,在ViewPager控件中设置流布局,再在流布局中设置几项TextView,给每一个TextView设置相关参数,事件等.关于ViewPager控件可以设置全屏幕滑动效果,当然也可以实现局部滑动效果,下面介绍导航菜单. 关于导航菜单,相信大家对它并不陌生,比如在新闻客户端中就经常使用左右滑动菜单来显示不同类别的新闻

  • Android实现下拉菜单Spinner效果

    Android 中下拉菜单,即如html中的<select>,关键在于调用setDropDownViewResource方法,以XML的方式定义下拉菜单要显示的模样 1.1.activity_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android

  • Android仿优酷圆形菜单学习笔记分享

    先来看看效果: 首先来分析一下: 这个菜单可以分成三个菜单: 1.一级菜单(即最内圈那个菜单) 2.二级菜单(即中间圈那个菜单) 3.三级菜单(即最外圈那个菜单) 首先,可以将这三个菜单使用相对布局 一级菜单只有一个按钮(即home),可以控制二级和三级菜单 二级菜单有三个按钮(即menu),中间那个按钮可以控制三级菜单 三级菜单有七个按钮 那先把布局文件先写出来,采用三个相对布局(即每个菜单采用一个相对布局) <RelativeLayout xmlns:android="http://s

  • Android仿微信顶/底部菜单栏效果

    本文要实现仿微信微信底部菜单栏+顶部菜单栏,采用ViewPage来做,每一个page对应一个XML,当手指在ViewPage左右滑动时,就相应显示不同的page(其实就是xml)并且同时改变底部菜单按钮的图片变暗或变亮,同时如果点击底部菜单按钮,左右滑动page(其实就是xml)并且改变相应按钮的亮度. 一.布局 1.顶部菜单布局,命名为top_layout.xml <?xml version="1.0" encoding="utf-8"?> <R

随机推荐