精华内容
下载资源
问答
  • android开发 仿美团团购顶部下拉菜单

    千次下载 热门讨论 2014-11-26 23:16:47
    android开发 仿美团团购顶部下拉菜单,我们在常用的电商或者旅游APP中,例如美团,手机淘宝等等,都能够看的到有那种下拉式的二级列表菜单
  • 主要给大家介绍android使用PopupWindow实现页面点击顶部弹出下拉菜单,实现此功能主要通过PopupWindow方法,代码也很简单,需要的朋友可以参考下
  • 感觉写的非常不错 特此记录下 本实例的自定义下拉菜单主要是继承PopupWindow类来实现的弹出窗体,各种布局效果可以根据自己定义设计。... 先上效果图如下:左边下拉菜单、中间下拉菜单、右边下拉菜单 ...

    本文转载至:https://blog.csdn.net/u013693649/article/details/49252963

    感觉写的非常不错  特此记录下

      本实例的自定义下拉菜单主要是继承PopupWindow类来实现的弹出窗体,各种布局效果可以根据自己定义设计。弹出的动画效果主要用到了translate、alpha、scale,具体实现步骤如下:

             先上效果图如下:左边下拉菜单、中间下拉菜单、右边下拉菜单

                                            

    1.主界面布局 activity_main.xml:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#ffffff" >
     
        <include
            android:id="@+id/main_top"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            layout="@layout/urm_top" />
     
        <TextView
            android:id="@+id/rule_line_tv"
            android:layout_width="match_parent"
            android:layout_height="0.5dp"
            android:layout_below="@id/main_top"
            android:background="@color/reserve_line" />
     
        <LinearLayout
            android:id="@+id/main_ll"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/rule_line_tv"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:padding="10dp" >
     
            <TextView
                android:id="@+id/left_tv"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:ellipsize="end"
                android:gravity="center_horizontal"
                android:maxLength="4"
                android:singleLine="true"
                android:text="我负责的线索" />
     
            <TextView
                android:id="@+id/middle_tv"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:ellipsize="end"
                android:gravity="center_horizontal"
                android:maxLength="4"
                android:singleLine="true"
                android:text="团队" />
     
            <TextView
                android:id="@+id/right_tv"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:ellipsize="end"
                android:gravity="center_horizontal"
                android:maxLength="4"
                android:singleLine="true"
                android:text="自定义" />
        </LinearLayout>
     
        <TextView
            android:id="@+id/rule_line01_tv"
            android:layout_width="match_parent"
            android:layout_height="0.5dp"
            android:layout_below="@id/main_ll"
            android:background="@color/reserve_line" />
     
        <TextView
            android:id="@+id/main_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="主界面" />
     
    </RelativeLayout>

    2.主界面测试类 MainActivity.java

    package com.popuptest;
     
    import java.util.ArrayList;
    import android.os.Bundle;
    import android.util.DisplayMetrics;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.Window;
    import android.widget.AdapterView;
    import android.widget.Button;
    import android.widget.ImageButton;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    import android.widget.AdapterView.OnItemClickListener;
    import android.widget.RelativeLayout.LayoutParams;
    import android.app.Activity;
     
    public class MainActivity extends Activity implements OnClickListener {
     
    	public static int screenW, screenH;
     
    	private ImageButton backBtn, createBtn;
    	private Button confirmBtn;
    	private TextView topTv;
    	private LinearLayout topll;
    	private ImageView topIv;
    	private TextView topLineTv;
     
    	private TopMiddlePopup middlePopup;
     
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		requestWindowFeature(Window.FEATURE_NO_TITLE);
    		setContentView(R.layout.activity_main);
    		getScreenPixels();
    		initWidget();
    	}
     
    	/**
    	 * 初始化控件
    	 */
    	private void initWidget() {
    		backBtn = (ImageButton) findViewById(R.id.urm_back_btn);
    		createBtn = (ImageButton) findViewById(R.id.urm_create_btn);
    		confirmBtn = (Button) findViewById(R.id.urm_confirm_btn);
     
    		topll = (LinearLayout) findViewById(R.id.urm_top_ll);
    		topIv = (ImageView) findViewById(R.id.urm_top_iv);
     
    		topLineTv = (TextView) findViewById(R.id.rule_line_tv);
     
    		topTv = (TextView) findViewById(R.id.urm_top_tv);
    		topTv.setText("企业客户");
     
    		backBtn.setOnClickListener(this);
    		createBtn.setOnClickListener(this);
    		confirmBtn.setOnClickListener(this);
    		topll.setOnClickListener(this);
     
    	}
     
    	/**
    	 * 设置弹窗
    	 * 
    	 * @param type
    	 */
    	private void setPopup(int type) {
    		middlePopup = new TopMiddlePopup(MainActivity.this, screenW, screenH,
    				onItemClickListener, getItemsName(), type);
    	}
     
    	/**
    	 * 设置弹窗内容
    	 * 
    	 * @return
    	 */
    	private ArrayList<String> getItemsName() {
    		ArrayList<String> items = new ArrayList<String>();
    		items.add("企业客户");
    		items.add("集团客户");
    		items.add("公海客户");
    		return items;
    	}
     
    	@Override
    	public void onClick(View v) {
    		switch (v.getId()) {
    		case R.id.urm_back_btn:
    			setPopup(1);
    			middlePopup.show(topLineTv);
    			break;
    		case R.id.urm_create_btn:
    			setPopup(2);
    			middlePopup.show(topLineTv);
    			break;
    		case R.id.urm_confirm_btn:
     
    			break;
    		case R.id.urm_top_ll:
    			setPopup(0);
    			middlePopup.show(topLineTv);
    			break;
    		}
    	}
     
    	/**
    	 * 弹窗点击事件
    	 */
    	private OnItemClickListener onItemClickListener = new OnItemClickListener() {
     
    		@Override
    		public void onItemClick(AdapterView<?> parent, View view, int position,
    				long id) {
    			System.out.println("--onItemClickListener--:");
    			middlePopup.dismiss();
    		}
    	};
     
    	/**
    	 * 获取屏幕的宽和高
    	 */
    	public void getScreenPixels() {
    		DisplayMetrics metrics = new DisplayMetrics();
    		getWindowManager().getDefaultDisplay().getMetrics(metrics);
    		screenW = metrics.widthPixels;
    		screenH = metrics.heightPixels;
    	}
     
    }

    3.自定义弹窗类 TopMiddlePopup.java

    package com.popuptest;
     
    import java.util.ArrayList;
    import android.content.Context;
    import android.graphics.drawable.ColorDrawable;
    import android.view.LayoutInflater;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.View.OnTouchListener;
    import android.view.ViewGroup.LayoutParams;
    import android.widget.LinearLayout;
    import android.widget.ListView;
    import android.widget.PopupWindow;
    import android.widget.AdapterView.OnItemClickListener;
     
    public class TopMiddlePopup extends PopupWindow {
     
    	private Context myContext;
    	private ListView myLv;
    	private OnItemClickListener myOnItemClickListener;
    	private ArrayList<String> myItems;
    	private int myWidth;
    	private int myHeight;
    	private int myType;
     
    	// 判断是否需要添加或更新列表子类项
    	private boolean myIsDirty = true;
     
    	private LayoutInflater inflater = null;
    	private View myMenuView;
     
    	private LinearLayout popupLL;
     
    	private PopupAdapter adapter;
     
    	public TopMiddlePopup(Context context) {
    		// TODO Auto-generated constructor stub
    	}
     
    	public TopMiddlePopup(Context context, int width, int height,
    			OnItemClickListener onItemClickListener, ArrayList<String> items,
    			int type) {
     
    		inflater = (LayoutInflater) context
    				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    		myMenuView = inflater.inflate(R.layout.top_popup, null);
     
    		this.myContext = context;
    		this.myItems = items;
    		this.myOnItemClickListener = onItemClickListener;
    		this.myType = type;
     
    		this.myWidth = width;
    		this.myHeight = height;
     
    		System.out.println("--myWidth--:" + myWidth + "--myHeight--:"
    				+ myHeight);
    		initWidget();
    		setPopup();
    	}
     
    	/**
    	 * 初始化控件
    	 */
    	private void initWidget() {
    		myLv = (ListView) myMenuView.findViewById(R.id.popup_lv);
    		popupLL = (LinearLayout) myMenuView.findViewById(R.id.popup_layout);
    		myLv.setOnItemClickListener(myOnItemClickListener);
     
    		if (myType == 1) {
    			android.widget.RelativeLayout.LayoutParams lpPopup = (android.widget.RelativeLayout.LayoutParams) popupLL
    					.getLayoutParams();
    			lpPopup.width = (int) (myWidth * 1.0 / 4);
    			lpPopup.setMargins(0, 0, (int) (myWidth * 3.0 / 4), 0);
    			popupLL.setLayoutParams(lpPopup);
    		} else if (myType == 2) {
    			android.widget.RelativeLayout.LayoutParams lpPopup = (android.widget.RelativeLayout.LayoutParams) popupLL
    					.getLayoutParams();
    			lpPopup.width = (int) (myWidth * 1.0 / 4);
    			lpPopup.setMargins((int) (myWidth * 3.0 / 4), 0, 0, 0);
    			popupLL.setLayoutParams(lpPopup);
    		}
    	}
     
    	/**
    	 * 设置popup的样式
    	 */
    	private void setPopup() {
    		// 设置AccessoryPopup的view
    		this.setContentView(myMenuView);
    		// 设置AccessoryPopup弹出窗体的宽度
    		this.setWidth(LayoutParams.MATCH_PARENT);
    		// 设置AccessoryPopup弹出窗体的高度
    		this.setHeight(LayoutParams.MATCH_PARENT);
    		// 设置AccessoryPopup弹出窗体可点击
    		this.setFocusable(true);
    		// 设置AccessoryPopup弹出窗体的动画效果
    		if (myType == 1) {
    			this.setAnimationStyle(R.style.AnimTopLeft);
    		} else if (myType == 2) {
    			this.setAnimationStyle(R.style.AnimTopRight);
    		} else {
    			//this.setAnimationStyle(R.style.AnimTop);
    			this.setAnimationStyle(R.style.AnimTopMiddle);
    		}
    		// 实例化一个ColorDrawable颜色为半透明
    		ColorDrawable dw = new ColorDrawable(0x33000000);
    		// 设置SelectPicPopupWindow弹出窗体的背景
    		this.setBackgroundDrawable(dw);
     
    		myMenuView.setOnTouchListener(new OnTouchListener() {
     
    			@Override
    			public boolean onTouch(View v, MotionEvent event) {
     
    				int height = popupLL.getBottom();
    				int left = popupLL.getLeft();
    				int right = popupLL.getRight();
    				System.out.println("--popupLL.getBottom()--:"
    						+ popupLL.getBottom());
    				int y = (int) event.getY();
    				int x = (int) event.getX();
    				if (event.getAction() == MotionEvent.ACTION_UP) {
    					if (y > height || x < left || x > right) {
    						System.out.println("---点击位置在列表下方--");
    						dismiss();
    					}
    				}
    				return true;
    			}
    		});
    	}
     
    	/**
    	 * 显示弹窗界面
    	 * 
    	 * @param view
    	 */
    	public void show(View view) {
    		if (myIsDirty) {
    			myIsDirty = false;
    			adapter = new PopupAdapter(myContext, myItems, myType);
    			myLv.setAdapter(adapter);
    		}
     
    		showAsDropDown(view, 0, 0);
    	}
     
    }

    4.自定义弹窗布局 top_popup.xml

    <?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" >
     
        <LinearLayout
            android:id="@+id/popup_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:background="#ffffff"
            android:orientation="vertical" >
     
            <ListView
                android:id="@+id/popup_lv"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:divider="@color/content_line"
                android:dividerHeight="0.5dp" >
            </ListView>
     
            <TextView
                android:layout_width="match_parent"
                android:layout_height="0.5dp"
                android:background="@color/reserve_line" />
        </LinearLayout>
     
    </RelativeLayout>

    5.弹窗类表适配器类 PopupAdapter

    package com.popuptest;
     
    import java.util.ArrayList;
    import android.content.Context;
    import android.view.Gravity;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.RelativeLayout.LayoutParams;
    import android.widget.TextView;
     
    public class PopupAdapter extends BaseAdapter {
    	private Context myContext;
    	private LayoutInflater inflater;
    	private ArrayList<String> myItems;
    	private int myType;
     
    	public PopupAdapter(Context context, ArrayList<String> items, int type) {
    		this.myContext = context;
    		this.myItems = items;
    		this.myType = type;
     
    		inflater = LayoutInflater.from(myContext);
     
    	}
     
    	@Override
    	public int getCount() {
    		return myItems.size();
    	}
     
    	@Override
    	public String getItem(int position) {
    		return myItems.get(position);
    	}
     
    	@Override
    	public long getItemId(int position) {
    		return 0;
    	}
     
    	@Override
    	public View getView(int position, View convertView, ViewGroup parent) {
    		PopupHolder holder = null;
    		if (convertView == null) {
    			holder = new PopupHolder();
    			convertView = inflater.inflate(R.layout.top_popup_item, null);
    			holder.itemNameTv = (TextView) convertView
    					.findViewById(R.id.popup_tv);
    			if (myType == 0) {
    				holder.itemNameTv.setGravity(Gravity.CENTER);
    			} else if (myType == 1) {
    				holder.itemNameTv.setGravity(Gravity.LEFT);
    			} else if (myType == 2) {
    				holder.itemNameTv.setGravity(Gravity.RIGHT);
    			}
    			convertView.setTag(holder);
    		} else {
    			holder = (PopupHolder) convertView.getTag();
    		}
    		String itemName = getItem(position);
    		holder.itemNameTv.setText(itemName);
    		return convertView;
    	}
     
    	private class PopupHolder {
    		TextView itemNameTv;
    	}
     
    }

    6.子item布局 top_popup_item.xml

    <?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="wrap_content"
        android:background="#ffffff"
        android:padding="10dp" >
     
        <TextView
            android:id="@+id/popup_tv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" 
            style="@style/urm_tv"/>
     
    </RelativeLayout>

    7.主界面顶部布局 urm_top.xml

    <?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="wrap_content"
        android:background="#eeeeee" >
     
        <ImageButton
            android:id="@+id/urm_back_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:background="@null"
            android:contentDescription="@string/app_name"
            android:src="@drawable/back" />
     
        <LinearLayout
            android:id="@+id/urm_top_ll"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:gravity="center_vertical"
            android:orientation="horizontal" >
     
            <TextView
                android:id="@+id/urm_top_tv"
                style="@style/main_tv_style"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="企业客户" />
     
            <ImageView
                android:id="@+id/urm_top_iv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:background="@null"
                android:contentDescription="@string/app_name"
                android:src="@drawable/switch02" />
        </LinearLayout>
     
        <RelativeLayout
            android:id="@+id/urm_top_right_rl"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true" >
     
            <ImageButton
                android:id="@+id/urm_create_btn"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@null"
                android:contentDescription="@string/app_name"
                android:src="@drawable/btn_add_2x" />
     
            <Button
                android:id="@+id/urm_confirm_btn"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@null"
                android:gravity="center_vertical"
                android:padding="10dp"
                android:text="确定"
                android:textColor="@color/blue2"
                android:textSize="18sp"
                android:visibility="gone" />
        </RelativeLayout>
     
        <ImageButton
            android:id="@+id/urm_search_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_toLeftOf="@id/urm_top_right_rl"
            android:background="@null"
            android:contentDescription="@string/app_name"
            android:src="@drawable/search"
            android:visibility="gone" />
     
    </RelativeLayout>

    8.styles.xml文件

    <resources>
     
        <!--
            Base application theme, dependent on API level. This theme is replaced
            by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
        -->
        <style name="AppBaseTheme" parent="android:Theme.Light">
            <!--
                Theme customizations available in newer API levels can go in
                res/values-vXX/styles.xml, while customizations related to
                backward-compatibility can go here.
            -->
        </style>
     
        <!-- Application theme. -->
        <style name="AppTheme" parent="AppBaseTheme">
            <!-- All customizations that are NOT specific to a particular API-level can go here. -->
        </style>
    
        <!--从顶部整齐的滑下-->
        <style name="AnimTop" parent="@android:style/Animation">
            <item name="android:windowEnterAnimation">@anim/push_top_in</item>
            <item name="android:windowExitAnimation">@anim/push_top_out</item>
        </style>
          <!--从右边滑下-->
         <style name="AnimTopRight" parent="@android:style/Animation">
            <item name="android:windowEnterAnimation">@anim/top_right_in</item>
            <item name="android:windowExitAnimation">@anim/top_right_out</item>
        </style>
          <!--从左边滑下-->
         <style name="AnimTopLeft" parent="@android:style/Animation">
            <item name="android:windowEnterAnimation">@anim/top_left_in</item>
            <item name="android:windowExitAnimation">@anim/top_left_out</item>
        </style>
          <!--从顶部中心发散出来-->
         <style name="AnimTopMiddle" parent="@android:style/Animation">
            <item name="android:windowEnterAnimation">@anim/top_middle_in</item>
            <item name="android:windowExitAnimation">@anim/top_middle_out</item>
        </style>
        
        <style name="main_tv_style">
            <item name="android:textSize">20sp</item>
            <item name="android:textColor">#000000</item>
        </style>
     
        <style name="urm_tv">
            <item name="android:textSize">18sp</item>
        </style>
    </resources>

    9.各种动画效果

    push_top_in.xml

    <?xml version="1.0" encoding="utf-8"?>
    <!-- 从屏幕上面进入 -->
    <set xmlns:android="http://schemas.android.com/apk/res/android" >
     
        <translate
            android:duration="500"
            android:fromYDelta="-100%p"
            android:toYDelta="0" />
     
        <alpha
            android:duration="500"
            android:fromAlpha="0.0"
            android:toAlpha="1.0" />
     
    </set>
    

    push_top_out.xml

    <?xml version="1.0" encoding="utf-8"?>
    <!-- 从屏幕上面退出 -->
    <set xmlns:android="http://schemas.android.com/apk/res/android" >
     
        <translate
            android:duration="500"
            android:fromYDelta="0"
            android:toYDelta="-100%p" />
     
        <alpha
            android:duration="500"
            android:fromAlpha="1.0"
            android:toAlpha="0.0" />
     
    </set>

    top_middle_in.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
     
        <scale
            android:duration="500"
            android:fillAfter="false"
            android:fromXScale="0.0"
            android:fromYScale="0.0"
            android:interpolator="@android:anim/accelerate_decelerate_interpolator"
            android:pivotX="50%"
            android:pivotY="0%"
            android:toXScale="1.0"
            android:toYScale="1.0" />
     
    </set>

    top_middle_out.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android" >
     
        <scale
            android:duration="500"
            android:fillAfter="false"
            android:fromXScale="1.0"
            android:fromYScale="1.0"
            android:interpolator="@android:anim/accelerate_decelerate_interpolator"
            android:pivotX="50%"
            android:pivotY="0%"
            android:toXScale="0.0"
            android:toYScale="0.0" />
     
    </set>

    top_right_in.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
     
        <scale
            android:duration="500"
            android:fillAfter="false"
            android:fromXScale="0.0"
            android:fromYScale="0.0"
            android:interpolator="@android:anim/accelerate_decelerate_interpolator"
            android:pivotX="100%"
            android:pivotY="0%"
            android:toXScale="1.0"
            android:toYScale="1.0" />
     
    </set>

    top_right_out.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android" >
     
        <scale
            android:duration="500"
            android:fillAfter="false"
            android:fromXScale="1.0"
            android:fromYScale="1.0"
            android:interpolator="@android:anim/accelerate_decelerate_interpolator"
            android:pivotX="100%"
            android:pivotY="0%"
            android:toXScale="0.0"
            android:toYScale="0.0" />
     
    </set>

    然后就可以了哦 根据自己的喜好去改代码就好了

    展开全文
  • Android仿微信下拉列表实现(加顶部菜单栏和底部菜单栏),具体看博文blog.csdn.net/evankaka/article/details/44179321
  • Android实现下拉导航选择菜单效果 ...我们可以让我们的应用顶部有左右滑动或进行切换的导航菜单,也可以为了增强用户体验在应用中添加这样的下拉导航选择菜单效果。  关于它的实现原理

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

      本文介绍在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

      最后,希望转载的朋友能够尊重作者的劳动成果,加上转载地址:http://www.cnblogs.com/hanyonglu/archive/2012/07/31/2617488.html 谢谢。

     

      完毕。^_^

     

    展开全文
  • 这是那个工程的Demo,有近1000行代码,我看了一个星期实在看不懂,我以前学C还不错,不过现在学java和android还是不熟悉,这个代码看似有监听的接口回调,我想做的是仿美团团购顶部的那个下拉菜单栏那样的,有二级...
  • Android仿大众点评、美团下拉菜单

    热门讨论 2013-04-15 16:06:22
    Android仿照大众点评和美团的顶部菜单,点击栏目弹出列表选择菜单,有二级菜单,也有单列的,很全面,也方便自己更改。
  • android页面开发中会碰到这种需求:点击页面顶部工具栏某个按钮时需要弹出下拉菜单。该工程利用PopupWindow实现了点击工具栏弹出下拉菜单的功能的主要实现类 .
  • android开发】使用PopupWindow实现页面点击顶部弹出下拉菜单 没有太多花样,也没有很复杂的技术,就是简单的PopupWindow的使用,可以实现点击弹出一个自定义的view,view里可以随便设计,常用的可以放一个...
    原文地址为:【android开发】使用PopupWindow实现页面点击顶部弹出下拉菜单


    没有太多花样,也没有很复杂的技术,就是简单的PopupWindow的使用,可以实现点击弹出一个自定义的view,view里可以随便设计,常用的可以放一个listview。


    demo中我只是一个点击展示,简单的使用了fade in out的动画效果,也没有精美的图片资源,看着也丑,不过这么短的时间,让你掌握一个很好用的技术,可以自己扩展,不很好么?



    废话不说了,直接上代码:

    MainActivity.java

    public class MainActivity extends Activity implements OnClickListener {
    
    	private PopupWindow popupwindow;
    	private Button button;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    
    		button = (Button) findViewById(R.id.button1);
    		button.setOnClickListener(this);
    
    	}
    
    	@Override
    	public void onClick(View v) {
    
    		switch (v.getId()) {
    		case R.id.button1:
    			if (popupwindow != null&&popupwindow.isShowing()) {
    				popupwindow.dismiss();
    				return;
    			} else {
    				initmPopupWindowView();
    				popupwindow.showAsDropDown(v, 0, 5);
    			}
    			break;
    		default:
    			break;
    		}
    
    	}
    
    	public void initmPopupWindowView() {
    
    		// // 获取自定义布局文件pop.xml的视图
    		View customView = getLayoutInflater().inflate(R.layout.popview_item,
    				null, false);
    		// 创建PopupWindow实例,200,150分别是宽度和高度
    		popupwindow = new PopupWindow(customView, 250, 280);
    		// 设置动画效果 [R.style.AnimationFade 是自己事先定义好的]
    		popupwindow.setAnimationStyle(R.style.AnimationFade);
    		// 自定义view添加触摸事件
    		customView.setOnTouchListener(new OnTouchListener() {
    
    			@Override
    			public boolean onTouch(View v, MotionEvent event) {
    				if (popupwindow != null && popupwindow.isShowing()) {
    					popupwindow.dismiss();
    					popupwindow = null;
    				}
    
    				return false;
    			}
    		});
    
    		/** 在这里可以实现自定义视图的功能 */
    		Button btton2 = (Button) customView.findViewById(R.id.button2);
    		Button btton3 = (Button) customView.findViewById(R.id.button3);
    		Button btton4 = (Button) customView.findViewById(R.id.button4);
    		btton2.setOnClickListener(this);
    		btton3.setOnClickListener(this);
    		btton4.setOnClickListener(this);
    
    	}
    
    }


    activity_main.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#000000"
        tools:context=".MainActivity" >
    
        <Button
            android:id="@+id/button1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:gravity="center"
            android:background="#C0C0C0"
            android:text="点击下拉列表" />
    
    </RelativeLayout>


    自定义view的xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#C0C0C0" >
    
        <Button
            android:id="@+id/button2"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:paddingRight="70dp"
            android:text="viviens" />
    
        <Button
            android:id="@+id/button3"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_below="@+id/button2"
            android:paddingRight="70dp"
            android:text="mryang" />
    
        <Button
            android:id="@+id/button4"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_below="@+id/button3"
            android:paddingRight="70dp"
            android:text="张晓达" />
    
    </RelativeLayout>


    动画效果:

    inputodown.xml 进入屏幕

    <?xml version="1.0" encoding="UTF-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android" >
    
        <translate
            android:duration="500"
            android:fromYDelta="-100%"
            android:toYDelta="0" />
    
    </set>

    outdowntoup.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android" >
    
        <translate
            android:duration="500"
            android:fromYDelta="0"
            android:toYDelta="-100%" />
    
    </set>


    styles.xml

        <style name="AnimationFade">
    
            <!-- PopupWindow左右弹出的效果 -->
            <item name="android:windowEnterAnimation">@anim/inuptodown</item>
            <item name="android:windowExitAnimation">@anim/outdowntoup</item>
        </style>




    实现效果:



    demo地址:

    http://download.csdn.net/detail/mad1989/5518035




    转载请注明本文地址:【android开发】使用PopupWindow实现页面点击顶部弹出下拉菜单
    展开全文

空空如也

空空如也

1 2 3 4 5
收藏数 90
精华内容 36
关键字:

android顶部下拉菜单