Android仿今日頭條APP實現(xiàn)下拉導(dǎo)航選擇菜單效果
本文實例為大家分享了在Android中如何實現(xiàn)下拉導(dǎo)航選擇菜單效果的全過程,供大家參考,具體內(nèi)容如下
關(guān)于下拉導(dǎo)航選擇菜單效果在新聞客戶端中用的比較多,當(dāng)然也可以用在其他的項目中,這樣可以很方便的選擇更多的菜單。我們可以讓我們的應(yīng)用頂部有左右滑動或進行切換的導(dǎo)航菜單,也可以為了增強用戶體驗在應(yīng)用中添加這樣的下拉導(dǎo)航選擇菜單效果。
關(guān)于它的實現(xiàn)原理,其實也是挺簡單的,就是使用PopupWindow來進行展現(xiàn),在顯示時控制其高度并配置以相應(yīng)的動畫效果。在PopupWindow中我使用GridView來控制里面的菜單項,每個菜單項對應(yīng)相應(yīng)的圖片和文字。當(dāng)然了,也有其他的實現(xiàn)方式。為了大家能夠清楚的理解,讓我們先看下效果圖,如下所示:
以上就是我實現(xiàn)的示例圖,大家已經(jīng)看到了,就是點擊應(yīng)用頂部中間的文字時展現(xiàn)出來,在我們點擊其中一項菜單時隱藏并加載相應(yīng)菜單的內(nèi)容,同時該菜單處于選中狀態(tài)。好了,下面就讓我們開始我們的實現(xiàn)過程,還是先看下程序結(jié)構(gòu)圖吧:

在程序結(jié)構(gòu)圖中,PulldownMenuView是對PopupWindow進行的封裝類,PulldownMenuItem是菜單項類,這是兩個重要的類。在我們點擊應(yīng)用頂部中間的文字時,要進行展現(xiàn),展現(xiàn)的同時,要實現(xiàn)對菜單的初始化工作,首先是初始化數(shù)據(jù),其主要代碼如下:
/**
* 初始化數(shù)據(jù),將數(shù)據(jù)加載到對應(yīng)的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代表當(dāng)前的選擇項,在初始化數(shù)據(jù)過程中,需要檢測哪項菜單被選中了,如果某項菜單被選中,則在展開時需要將該項菜單圖片和文字顏色設(shè)置成相應(yīng)狀態(tài),表示該項菜單被選中。在初始化過程中分為三種情況:第一種是菜單項既有圖片也有文字;第二種是菜單項只有文字;第三種是菜單項只有圖片;所以在上面代碼中需要進行相應(yīng)判斷。上面是初始化菜單中的數(shù)據(jù),下面是初始化菜單中的內(nèi)容:
/**
* 初始化菜單內(nèi)容
* @param context
* @param columns 菜單的列數(shù)
* @return
*/
private GridView getMenuGirdView(Context context, int columns){
if (menuMenuItems.isEmpty()){
// 初始化菜單數(shù)據(jù)
initData();
}
if (null != menuGridView){
return menuGridView;
}
GridView gridView = new GridView(context);
gridView.setLayoutParams(new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
// 設(shè)置數(shù)據(jù)適配器
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;
}
初始化菜單之后,就需要我們菜單中相應(yīng)的數(shù)據(jù),設(shè)置數(shù)據(jù)比較容易,只需要三個數(shù)組即可:第一個數(shù)組代表菜單項文字內(nèi)容;第二個數(shù)組代表菜單項圖片資源,第三個數(shù)組代表菜單項被選中的圖片資源。如下代碼:
/**
* 新聞菜單項圖片資源
*/
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 = {
"今日頭條","國內(nèi)","國際","社會","體育","NBA","博客","讀書",
"娛樂","軍事","財經(jīng)","科技","手機","女性","汽車","房產(chǎn)"
};
菜單項使用GridView實現(xiàn),我們還需要設(shè)置每個菜單項的監(jiān)聽事件,在選中一項菜單后或是點擊返回鍵或點擊菜單鍵時實現(xiàn)隱藏,代碼如下:
/**
* 設(shè)置菜單項監(jiān)聽事件
* @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()方法中,主要是實現(xiàn)菜單的顯示與隱藏。在show()方法中,要計算每行存放的菜單數(shù)、設(shè)置相應(yīng)的高度、菜單整體的背景、動畫效果、菜單顯示的位置等效果。具體不再詳述。
我們在顯示下拉導(dǎo)航選擇菜單前還需要配置菜單相應(yīng)的參數(shù),比如顯示位置、背景圖片、高度等。這就是在MenuUtility類中要實現(xiàn)的,代碼如下:
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;
// 文字內(nèi)容
private String[] texts = null;
// 菜單高度
private int height = 0;
private View anchorView = null;
/**
* 默認的構(gòu)造器
*/
public MenuUtility() {
// TODO Auto-generated constructor stub
}
/**
* 帶Context的構(gòu)造器
* @param context
*/
public MenuUtility(Context context) {
// TODO Auto-generated constructor stub
this(context,null,null,0,null);
}
/**
* 帶多參的構(gòu)造器
* @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;
}
/**
* 設(shè)置圖片資源
* @param imageRes
*/
public void setImageRes(int[] imageRes){
this.imageRes = imageRes;
}
/**
* 設(shè)置文字內(nèi)容
* @param texts
*/
public void setTexts(String[] texts){
this.texts = texts;
}
/**
* 設(shè)置高度
* @param height
*/
public void setHeight(int height){
this.height = height;
}
/**
* 設(shè)置顯示的位置
* @param anchor
*/
public void setAnchorView(View anchor){
anchorView = anchor;
}
/**
* 獲取PulldownMenuView對象
* 以下拉的形式展現(xiàn)出來菜單
* @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對象
* 以向上彈出的方式展現(xiàn)出來菜單
* @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實現(xiàn)我們的效果,當(dāng)然了,它也可以以向上彈出的方式展現(xiàn)。在我這個示例中,需要它展現(xiàn)的位置是在頂部橫條下面展現(xiàn),所以設(shè)置:
menu.setAnchorView(anchorView);
另外,在MainActivity中需要設(shè)置它的顯示高度,在這里高度需要在頂部橫條和底部RadioGroup之間,這就需要我們獲取手機屏幕的高度減去頂部橫條的高度,再減去底部RadioGroup的高度,最后減去手機菜單欄的高度。在點擊某項菜單后,還需要將頂部中間文字和右邊三角圖片進行相應(yīng)的變換。代碼如下所示:
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實現(xiàn)下拉導(dǎo)航選擇菜單效果
* @Description: Android實現(xiàn)下拉導(dǎo)航選擇菜單效果
* @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);
}
// 頂部今日頭條事件監(jiān)聽器
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的高度時需要注意在布局文件中設(shè)置其相應(yīng)的layout_height,否則,我們是獲取不到其高度的。程序中間的主體部分是截取了幾張圖片,這個大家可以根據(jù)自己的需要設(shè)置成自己的數(shù)據(jù)格式。這點知道就可以了。
以上便是Android中實現(xiàn)下拉導(dǎo)航選擇菜單效果的實現(xiàn)過程,是在PopupWindow中嵌入GridView實現(xiàn),當(dāng)然也可以在PopupWindow中嵌入ListView等各種控件實現(xiàn)相應(yīng)的效果,也可以對PopupWindow實現(xiàn)各種和樣的變幻效果,具體過程這里就不再詳述了,有興趣的朋友我們可以一起探討。
源碼下載:下拉導(dǎo)航選擇菜單
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android制作微信app頂部menu菜單(ActionBar)
- Android App中DrawerLayout抽屜效果的菜單編寫實例
- Android界面設(shè)計(APP設(shè)計趨勢 左側(cè)隱藏菜單右邊顯示content)
- Android實現(xiàn)頂部導(dǎo)航菜單左右滑動效果
- Android滑動優(yōu)化高仿QQ6.0側(cè)滑菜單(滑動優(yōu)化)
- Android實現(xiàn)自定義滑動式抽屜菜單效果
- android RecyclerView側(cè)滑菜單,滑動刪除,長按拖拽,下拉刷新上拉加載
- Android仿微信滑動彈出編輯、刪除菜單效果、增加下拉刷新功能
- Android利用滑動菜單框架實現(xiàn)滑動菜單效果
- Android實現(xiàn)美團APP的底部滑動菜單
相關(guān)文章
Android Studio3.6.+ 插件搜索不到終極解決方案(圖文詳解)
這篇文章主要介紹了Android Studio3.6.+ 插件搜索不到終極解決方案,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05
Android編程之SurfaceView學(xué)習(xí)示例詳解
這篇文章主要介紹了Android編程之SurfaceView學(xué)習(xí)示例,結(jié)合實例分析了SurfaceView的功能、使用方法與注意事項,具有一定參考借鑒價值,需要的朋友可以參考下2015-10-10
自定義TextView跑馬燈效果可控制啟動/停止/速度/焦點
Android自帶的跑馬燈效果不太好控制,不能控制速度,不能即時停止和啟動,而且還受焦點的影響不已,由于項目需求需所以自己寫了一個自定義的TextView,感興趣的朋友可以了解下2013-01-01
Android平臺預(yù)置GMS包后關(guān)機鬧鐘失效問題及解決方法
這篇文章主要介紹了Android平臺預(yù)置GMS包后,關(guān)機鬧鐘失效,本文給大家分享問題原因及解決方法,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09
android使用ItemDecoration給RecyclerView 添加水印
本篇文章主要介紹了android使用ItemDecoration給RecyclerView 添加水印,介紹了自定義Drawable來完成水印圖片和使用ItemDecoration來布局水印,有興趣的可以了解一下。2017-02-02
Android簡單實現(xiàn)動態(tài)權(quán)限獲取相機權(quán)限及存儲空間等多權(quán)限
這篇文章主要介紹了Android簡單實現(xiàn)動態(tài)權(quán)限獲取相機權(quán)限及存儲空間等多權(quán)限,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下2022-07-07

