Android實現頂部導航選單左右滑動效果

Android實現頂部導航選單左右滑動效果
1 Star2 Stars3 Stars4 Stars5 Stars 給文章打分!
Loading...

本文給大家介紹在Android中如何實現頂部導航選單左右滑動效果,具體內容如下
第一種解決方案:
實現原理是使用android-support-v4.jar包中ViewPager控制元件,在ViewPager控制元件中設定流佈局,再在流佈局中設定幾項TextView,給每一個TextView設定相關引數,事件等。關於ViewPager控制元件可以設定全螢幕滑動效果,當然也可以實現區域性滑動效果,下面介紹導航選單。
關於導航選單,相信大家對它並不陌生,比如在新聞客戶端中就經常使用左右滑動選單來顯示不同類別的新聞。網上也有關於這方面的一些示例,但是許多都是使用Tabhost來做的,實現了圖片平滑動畫效果,但沒有實現選單左右滑動的效果。我們先來看下本示例的效果圖:

以上是效果圖,以下讓我們來看來如何才能實現,先建立程式結構,結構圖如下:

在程式中,我們需要匯入android-support-v4.jar包。在SlideMenuUtil類中設定導航選單項標籤,如下: 


package com.slide.util; 
/**
* 滑動選單選項類
* @Description: 滑動選單選項類
* @FileName: SlideMenuUtil.java 
* @Package com.slide.util 
* @Author Hanyonglu 
* @Date 2012-4-20 下午04:51:24 
* @Version V1.0
*/
public class SlideMenuUtil {
// 選單選項
public static String ITEM_MOBILE = "移動";
public static String ITEM_WEB = "Web";
public static String ITEM_CLOUD = "雲端計算";
public static String ITEM_DATABASE = "資料庫";
public static String ITEM_EMBED = "嵌入式";
public static String ITEM_SERVER = "伺服器";
public static String ITEM_DOTNET = ".NET";
public static String ITEM_JAVA = "JAVA";
public static String ITEM_SAFE = "安全";
public static String ITEM_DOMAIN = "業界";
public static String ITEM_RESEASRCH = "研發";
public static String ITEM_MANAGE = "管理";
// 選單項計數器
public int count = 0;
}

為了實現導航選單上的左右圖片,需要在main.xml佈局檔案中設定相對佈局。

這個示例中,是把左右導航的圖片顯示在文字上方,在點選上圖中右三角圖片時會顯示下一個頁面導航,具體大家可以看下面程式碼。
main.xml中設定左右圖片的相對佈局程式碼:
        


<RelativeLayout 
       android:id="@ id/linearLayout01"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<android.support.v4.view.ViewPager
android:id="@ id/slideMenu"
android:layout_width="fill_parent"
android:layout_height="35dp"
android:background="@drawable/top_bg" />
<RelativeLayout
android:id="@ id/linearLayout01"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:id="@ id/ivPreviousButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:paddingTop="10dp"
android:paddingLeft="5dp"
android:visibility="invisible"
android:src="@drawable/previous_button" />
</RelativeLayout>
<RelativeLayout
android:id="@ id/linearLayout01"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:id="@ id/ivNextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:paddingTop="10dp"
android:paddingRight="5dp"
android:visibility="invisible"
android:src="@drawable/next_button" />
<!-- 
<ImageView
android:id="@ id/ivMenuBackgroundCopy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:paddingTop="2dp"
android:src="@drawable/menu_bg" />
-->
</RelativeLayout>
<ImageView
android:id="@ id/ivMenuBackground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="2dp"
android:layout_toRightOf="@ id/ivPreviousButton"
android:paddingTop="2dp"
android:visibility="gone"
android:src="@drawable/menu_bg" />
</RelativeLayout> 

程式碼中id為ivMenuBackground的圖片是為了在點選一項選單後設定其背景圖片,選單中預設選中第一項“移動”。
在程式結構圖中的item_xxx.xml是為了在選一項選單後顯示下面的佈局內容。這只是個示例,有興趣的朋友可以改造成其它的佈局內容。

使用二維陣列儲存導航選單項:   


private String[][] menus = {{SlideMenuUtil.ITEM_MOBILE,SlideMenuUtil.ITEM_WEB, 
SlideMenuUtil.ITEM_CLOUD,SlideMenuUtil.ITEM_DATABASE},
{SlideMenuUtil.ITEM_EMBED,SlideMenuUtil.ITEM_SERVER,
SlideMenuUtil.ITEM_DOTNET,SlideMenuUtil.ITEM_JAVA},
{SlideMenuUtil.ITEM_SAFE,SlideMenuUtil.ITEM_DOMAIN,
SlideMenuUtil.ITEM_RESEASRCH,SlideMenuUtil.ITEM_MANAGE}};

上例程式碼中:陣列的第一維是用來顯示幾頁資料,第二維是用來顯示每一頁中的幾個選單項。
在剛開始時,需要初始化導航選單內容:


LayoutInflater inflater = getLayoutInflater(); 
menuViews = new ArrayList<View>(); 
SlideMenuLayout menu = new SlideMenuLayout(this);
for(int i = 0;i < menus.length;i  ){
menuViews.add(menu.getSlideMenuLinerLayout(menus[i],screenWidth));
}
main = (ViewGroup)inflater.inflate(R.layout.main, null);

其中,menuViews是用來裝載頁面佈局控制元件,有3個頁面menuViews就有3項。screenWidth是代表螢幕寬度。這裡還使用到SlideMenuLayout類的例項方法:getSlideMenuLinerLayout(String[] menuTextViews,int layoutWidth)
menuTextViews是代表每頁中有幾項選單,layoutWidth是螢幕寬度。該方法中程式碼如下:


/** 
* 頂部滑動選單佈局
* @param menuTextViews
* @param layoutWidth
*/
public View getSlideMenuLinerLayout(String[] menuTextViews,int layoutWidth){
// 包含TextView的LinearLayout
LinearLayout menuLinerLayout = new LinearLayout(activity);
menuLinerLayout.setOrientation(LinearLayout.HORIZONTAL);
// 引數設定
LinearLayout.LayoutParams menuLinerLayoutParames = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, 
LinearLayout.LayoutParams.WRAP_CONTENT,
1);
menuLinerLayoutParames.gravity = Gravity.CENTER_HORIZONTAL;
// 新增TextView控制元件
for(int i = 0;i < menuTextViews.length; i  ){
TextView tvMenu = new TextView(activity);
// 設定標識值
tvMenu.setTag(menuTextViews[i]);
tvMenu.setLayoutParams(new LayoutParams(layoutWidth / 4,30)); 
tvMenu.setPadding(30, 14, 30, 10);
tvMenu.setText(menuTextViews[i]);
tvMenu.setTextColor(Color.WHITE);
tvMenu.setGravity(Gravity.CENTER_HORIZONTAL);
tvMenu.setOnClickListener(SlideMenuOnClickListener);
// 選單項計數
menuUtil.count   ;
// 設定第一個選單項背景
if(menuUtil.count == 1){
tvMenu.setBackgroundResource(R.drawable.menu_bg);
}
menuLinerLayout.addView(tvMenu,menuLinerLayoutParames);
menuList.add(tvMenu);
}
return menuLinerLayout;
}

上例程式碼只是初始化選單效果,我是使用TextView做為每一項選單,當然還要給每一項選單設定事件,事件程式碼如下:


// 單個選單事件 
OnClickListener SlideMenuOnClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String menuTag = v.getTag().toString();
if(v.isClickable()){
textView = (TextView)v;
Log.i("SlideMenu", 
"width:"   textView.getWidth()   
"height:"   textView.getHeight());
textView.setBackgroundResource(R.drawable.menu_bg);
for(int i = 0;i < menuList.size();i  ){
if(!menuTag.equals(menuList.get(i).getText())){
menuList.get(i).setBackgroundDrawable(null);
}
}
// 點選選單時改變內容
slideMenuOnChange(menuTag);
}
}
};

上面程式碼中的for迴圈是為了清除其它選單項的背景,slideMenuOnChange(menuTag)方法是為了顯示下面的內容。該方法中程式碼如下:


// 點選時改內容 
private void slideMenuOnChange(String menuTag){
LayoutInflater inflater = activity.getLayoutInflater();
ViewGroup llc = (ViewGroup)activity.findViewById(R.id.linearLayoutContent);
llc.removeAllViews();
if(menuTag.equals(SlideMenuUtil.ITEM_MOBILE)){
llc.addView(inflater.inflate(R.layout.item_mobile, null));
}else if(menuTag.equals(SlideMenuUtil.ITEM_WEB)){
llc.addView(inflater.inflate(R.layout.item_web, null));
}else if(menuTag.equals(SlideMenuUtil.ITEM_CLOUD)){
llc.addView(inflater.inflate(R.layout.item_cloud, null));
}else if(menuTag.equals(SlideMenuUtil.ITEM_DATABASE)){
llc.addView(inflater.inflate(R.layout.item_database, null));
}else if(menuTag.equals(SlideMenuUtil.ITEM_EMBED)){
llc.addView(inflater.inflate(R.layout.item_embed, null));
}else if(menuTag.equals(SlideMenuUtil.ITEM_SERVER)){
llc.addView(inflater.inflate(R.layout.item_server, null));
}else if(menuTag.equals(SlideMenuUtil.ITEM_DOTNET)){
llc.addView(inflater.inflate(R.layout.item_dotnet, null));
}else if(menuTag.equals(SlideMenuUtil.ITEM_JAVA)){
llc.addView(inflater.inflate(R.layout.item_java, null));
}else if(menuTag.equals(SlideMenuUtil.ITEM_SAFE)){
llc.addView(inflater.inflate(R.layout.item_safe, null));
}else if(menuTag.equals(SlideMenuUtil.ITEM_DOMAIN)){
llc.addView(inflater.inflate(R.layout.item_domain, null));
}else if(menuTag.equals(SlideMenuUtil.ITEM_RESEASRCH)){
llc.addView(inflater.inflate(R.layout.item_research, null));
}else if(menuTag.equals(SlideMenuUtil.ITEM_MANAGE)){
llc.addView(inflater.inflate(R.layout.item_manage, null));
}
}

另外,為了設定左右導航選單中的圖片,需要在ViewPager控制元件中的onPageSelected監聽事件中更改圖片狀態:


@Override 
public void onPageSelected(int arg0) {
int pageCount = menuViews.size() - 1;
pagerIndex = arg0;
// 顯示右邊導航圖片
if(arg0 >= 0 && arg0 < pageCount){
imageNext.setVisibility(View.VISIBLE);
}else{
imageNext.setVisibility(View.INVISIBLE);
}
// 顯示左邊導航圖片
if(arg0 > 0 && arg0 <= pageCount){
imagePrevious.setVisibility(View.VISIBLE);
}else{
imagePrevious.setVisibility(View.INVISIBLE);
}
} 

說明:如果有多個頁面,則直接顯示右邊導航圖片:


if(menuViews.size() > 1){ 
imageNext.setVisibility(View.VISIBLE);
}

如果到達最後一頁時,則隱藏右邊導航圖片;如果當前頁不是第一頁,則直接顯示左邊導航圖片。
另外,還需要給這兩個導航圖片設定單擊事件,在點選時直接顯示下一頁選單或是上一頁選單:


// 右導航圖片按鈕事件 
class ImageNextOnclickListener implements OnClickListener{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
pagerIndex   ;
viewPager.setCurrentItem(pagerIndex);
}
}
// 左導航圖片按鈕事件
class ImagePreviousOnclickListener implements OnClickListener{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
pagerIndex --;
viewPager.setCurrentItem(pagerIndex);
}
}

到此,第一種解決方案大致思路和程式碼就已經完了,不過我這裡的實現效果是在滑動時直接顯示下一頁選單,本頁選單就給隱藏掉了。有的朋友可能注意到,要想實現一點一點向左滑動或是向右滑動,而不是整個頁面的滑動,也就是如果沒有滑到下一頁會反彈到原來的那頁,就不能用這個方法了,那麼就需要用到HorizontalScrollView,關於HorizontalScrollView實現的滑動選單使用及示例,請看下面的第二種解決方案。
另外,在本示例中我沒有實現背景圖片的平滑向右或是向左的動畫效果,有興趣的的朋友可以把這樣的效果加上,網上有一些實現這樣的效果示例。

第二種解決方案:
第二種解決方案我是採用的HorizontalScrollView實現的,這種佈局可以實現橫向滑動效果,但要注意只能有一個直接子標籤。這種方案相比第一種方案要簡單得多,只需要設定好佈局就可以了。先看下示例執行效果:

上圖中實現的導航選單左右滑動效果可以讓選單逐步滑動,我這個示例中沒有出現反彈的現象。好了,讓我們看下佈局程式碼:


<HorizontalScrollView 
android:layout_width="match_parent"
android:layout_height="35dp"
android:scrollbars="none" >
<LinearLayout
android:id="@ id/linearLayoutMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/top_bg"
android:gravity="center_vertical" >
</LinearLayout>
</HorizontalScrollView> 

其中的選單項我仍然是用TextView控制元件,我這裡是使用程式碼新增的TextView,如下: 


private void setSlideMenu(){ 
// 包含TextView的LinearLayout
LinearLayout menuLinerLayout = (LinearLayout) findViewById(R.id.linearLayoutMenu);
menuLinerLayout.setOrientation(LinearLayout.HORIZONTAL);
// 引數設定
LinearLayout.LayoutParams menuLinerLayoutParames = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, 
LinearLayout.LayoutParams.WRAP_CONTENT,
1);
menuLinerLayoutParames.gravity = Gravity.CENTER_HORIZONTAL;
// 新增TextView控制元件
for(int i = 0;i < menus.length;i  ){
TextView tvMenu = new TextView(this);
tvMenu.setLayoutParams(new LayoutParams(30,30)); 
tvMenu.setPadding(30, 14, 30, 10);
tvMenu.setText(menus[i]);
tvMenu.setTextColor(Color.WHITE);
tvMenu.setGravity(Gravity.CENTER_HORIZONTAL);
menuLinerLayout.addView(tvMenu,menuLinerLayoutParames);
}
}

怎麼樣,感覺不難吧。如果要在<HorizontalScrollView>上方標題或是下方設定內容,我們可以把<HorizontalScrollView>巢狀在其它的佈局中,相信這個大家都可以做到,不再多說。
另外,還可以使用Gallery來實現導航選單滑動,關於Gallery如何實現,本文就不再詳述,有興趣的朋友可以查詢幫助文件。
原文地址:http://www.cnblogs.com/hanyonglu/archive/2012/04/21/2462311.html
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援指令碼之家。

您可能感興趣的文章:

Android滑動優化高仿QQ6.0側滑選單(滑動優化)Android仿微信滑動彈出編輯、刪除選單效果、增加下拉重新整理功能Android實現自定義滑動式抽屜效果選單Android仿QQ滑動彈出選單標記已讀、未讀訊息android RecyclerView側滑選單,滑動刪除,長按拖拽,下拉重新整理上拉載入Android程式開發之使用Design包實現QQ動畫側滑效果和滑動選單導航Android模仿美團頂部的滑動選單例項程式碼Android側滑選單和輪播圖之滑動衝突問題Android解決viewpager巢狀滑動衝突並保留側滑選單功能Android實現上下選單雙向滑動效果

相關文章

Android 開發 最新文章