关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » 安卓开发 »Android仿手机淘宝多级下拉菜单

    Android仿手机淘宝多级下拉菜单

    2014-10-01 00:00:00 出处:mandmLee
    分享

    我们在常用的电商或者旅游APP中,例如美团,手机淘宝等等,都能够看的到有那种下拉式的二级列表菜单。具体如图所示:

    上面两张图就是美团的一个二级列表菜单的一个展示。我相信很多人都想开发一个跟它一样的功能放到自己的APP中。好,接下来我们就开始动手,解决它。

    1,结构分析

    首先,我们给出这个下来菜单需要的组建。我们用线框图来分析。

    1)如上图所示,最外围的是一个Activity,顶部包含了一个View的容器,这个容器主要是装载ToggleButton来实现诸如美团里面的“美食,全城,理我最近,刷选”这一行。这一行一点就会弹出对应的下来菜单。

    2)下拉菜单是如何实现的呢?,这里我们利用了PopupWindow来实现这一弹出式窗口。然后我们在弹出式窗口里面再定义我们的下来列表项,是单列还是二级菜单,都是由里面来定。

    3)不同的菜单,需要一级或者需要二级,在这里根据我的需求而变动。我们在PopupWindow上面加一个自定义的LeftView,或者是MiddleView,RightView。主要是一个ToggleButton,你弹出一个窗口,你就定制一个窗口。

    3)视图里面嵌入ListView,就形成了列表项。

    好分析就到上面为止,接下来我们一步步的说明实现。

    2,项目结构

    本项目的项目结构如图所示:

    1) Adapter。适配器,主要是为ListView提供数据适配的。

    2)MainActivity。主活动页面。

    3)ExpandTabView。本项目的核心类,它包含ToggleButton容器和PopupWindow,是控制弹出窗口的核心类。

    4)ViewLeft,ViewMiddle,ViewRight。是弹出里面嵌套的类,实现不同的列表菜单。

    3,MainActivity

    承载所有元素。看代码比看文字实在。

    package com.example.expandtabview;
    
    import java.util.ArrayList;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Toast;
    
    import com.example.view.ExpandTabView;
    import com.example.view.ViewLeft;
    import com.example.view.ViewMiddle;
    import com.example.view.ViewRight;
    
    public class MainActivity extends Activity {
    	private static final String TAG = "MainActivity";
    	private ExpandTabView expandTabView;
    	private ArrayList<View> mViewArray = new ArrayList<View>();
    	private ViewLeft viewLeft;
    	private ViewMiddle viewMiddle;
    	private ViewRight viewRight;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		initView();
    		initVaule();
    		initListener();
    
    	}
    
    	private void initView() {
    		Log.d(TAG,"initView");
    		expandTabView = (ExpandTabView) findViewById(R.id.expandtab_view);
    		viewLeft = new ViewLeft(this);
    		viewMiddle = new ViewMiddle(this);
    		viewRight = new ViewRight(this);
    
    	}
    
    	private void initVaule() {
    		Log.d(TAG,"initValue");
        	mViewArray.add(viewLeft);
    		mViewArray.add(viewMiddle);
    		mViewArray.add(viewRight);
    		ArrayList<String> mTextArray = new ArrayList<String>();
    		mTextArray.add("距离");
    		mTextArray.add("区域");
    		mTextArray.add("距离");
    		expandTabView.setValue(mTextArray, mViewArray);//将三个下拉列表设置进去
    		expandTabView.setTitle(viewLeft.getShowText(), 0);
    		expandTabView.setTitle(viewMiddle.getShowText(), 1);
    		expandTabView.setTitle(viewRight.getShowText(), 2);
    
    	}
    
    	private void initListener() {
    		Log.d(TAG,"initListener");
    		viewLeft.setOnSelectListener(new ViewLeft.OnSelectListener() {
    
    			@Override
    			public void getValue(String distance, String showText) {
    				Log.d("ViewLeft", "OnSelectListener, getValue");
    				onRefresh(viewLeft, showText);
    			}
    		});
    
    		viewMiddle.setOnSelectListener(new ViewMiddle.OnSelectListener() {
    
    			@Override
    			public void getValue(String showText) {
    				Log.d("ViewMiddle","OnSelectListener, getValue");
    				onRefresh(viewMiddle,showText);
    
    			}
    		});
    
    		viewRight.setOnSelectListener(new ViewRight.OnSelectListener() {
    
    			@Override
    			public void getValue(String distance, String showText) {
    				Log.d("ViewRight","OnSelectListener, getValue");
    				onRefresh(viewRight, showText);
    			}
    		});
    
    	}
    
    	private void onRefresh(View view, String showText) {
    		Log.d(TAG,"onRefresh,view:"+view+",showText:"+showText);
    		expandTabView.onPressBack();
    		int position = getPositon(view);
    		if (position >= 0 && !expandTabView.getTitle(position).equals(showText)) {
    			expandTabView.setTitle(showText, position);
    		}
    		Toast.makeText(MainActivity.this, showText, Toast.LENGTH_SHORT).show();
    
    	}
    
    	private int getPositon(View tView) {
    		Log.d(TAG,"getPosition");
    		for (int i = 0; i < mViewArray.size(); i++) {
    			if (mViewArray.get(i) == tView) {
    				return i;
    			}
    		}
    		return -1;
    	}
    
    	@Override
    	public void onBackPressed() {
    
    		if (!expandTabView.onPressBack()) {
    			finish();
    		}
    
    	}
    
    }

    4 ,ExpandTabView

    最主要就是如何处理当我们点击这些ToggleButton的时候要弹出或者收起这些PopupWindow。

    package com.example.view;
    
    import java.util.ArrayList;
    
    import com.example.expandtabview.R;
    
    import android.app.Activity;
    import android.content.Context;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.widget.LinearLayout;
    import android.widget.PopupWindow;
    import android.widget.PopupWindow.OnDismissListener;
    import android.widget.RelativeLayout;
    import android.widget.TextView;
    import android.widget.ToggleButton;
    
    /**
     * 菜单控件头部,封装了下拉动画,动态生成头部按钮个数
     * 
     * @author zengjinlong
     */
    
    public class ExpandTabView extends LinearLayout implements OnDismissListener {
    	private static final String TAG = "ExpandTabView";
    	private ToggleButton selectedButton;
    	private ArrayList<String> mTextArray = new ArrayList<String>();
    	private ArrayList<RelativeLayout> mViewArray = new ArrayList<RelativeLayout>();
    	private ArrayList<ToggleButton> mToggleButton = new ArrayList<ToggleButton>();
    	private Context mContext;
    	private final int SMALL = 0;
    	private int displayWidth;
    	private int displayHeight;
    	private PopupWindow popupWindow;
    	private int selectPosition;
    
    	public ExpandTabView(Context context) {
    		super(context);
    		init(context);
    	}
    
    	public ExpandTabView(Context context, AttributeSet attrs) {
    		super(context, attrs);
    		init(context);
    	}
    
    	/**
    	 * 根据选择的位置设置tabitem显示的值
    	 */
    	public void setTitle(String valueText, int position) {
    		if (position < mToggleButton.size()) {
    			mToggleButton.get(position).setText(valueText);
    		}
    	}
    
    	public void setTitle(String title){
    
    	}
    	/**
    	 * 根据选择的位置获取tabitem显示的值
    	 */
    	public String getTitle(int position) {
    		if (position < mToggleButton.size() && mToggleButton.get(position).getText() != null) {
    			return mToggleButton.get(position).getText().toString();
    		}
    		return "";
    	}
    
    	/**
    	 * 设置tabitem的个数和初始值
    	 * @param textArray 标题数组
    	 * @param viewArray 控件数组
    	 */
    	public void setValue(ArrayList<String> textArray, ArrayList<View> viewArray) {
    		if (mContext == null) {
    			return;
    		}
    		LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    		Log.d(TAG,"setValue");
    		mTextArray = textArray;
    		for (int i = 0; i < viewArray.size(); i++) {
    			final RelativeLayout r = new RelativeLayout(mContext);
    			int maxHeight = (int) (displayHeight * 0.7);
    			RelativeLayout.LayoutParams rl = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, maxHeight);
    			rl.leftMargin = 10;
    			rl.rightMargin = 10;
    			r.addView(viewArray.get(i), rl);
    			mViewArray.add(r);
    			r.setTag(SMALL);
    			ToggleButton tButton = (ToggleButton) inflater.inflate(R.layout.toggle_button, this, false);
    			addView(tButton);
    			View line = new TextView(mContext);
    			line.setBackgroundResource(R.drawable.choosebar_line);
    			if (i < viewArray.size() - 1) {
    				LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(2, LinearLayout.LayoutParams.MATCH_PARENT);
    				addView(line, lp);
    			}
    			mToggleButton.add(tButton);
    			tButton.setTag(i);
    			tButton.setText(mTextArray.get(i));
    
    			r.setOnClickListener(new OnClickListener() {
    				@Override
    				public void onClick(View v) {
    					Log.d("RelativeLayout","view:"+v);
    					onPressBack();
    				}
    			});
    
    			r.setBackgroundColor(mContext.getResources().getColor(R.color.popup_main_background));
    			tButton.setOnClickListener(new OnClickListener() {
    				@Override
    				public void onClick(View view) {
    					Log.d("tButton","setOnClickListener(l)");
    					// initPopupWindow();
    					ToggleButton tButton = (ToggleButton) view;
    
    					if (selectedButton != null && selectedButton != tButton) {
    						selectedButton.setChecked(false);
    					}
    					selectedButton = tButton;
    					selectPosition = (Integer) selectedButton.getTag();
    					startAnimation();
    					if (mOnButtonClickListener != null && tButton.isChecked()) {
    						mOnButtonClickListener.onClick(selectPosition);
    					}
    				}
    			});
    		}// for..
    	}
    
    	private void startAnimation() {
    		Log.d(TAG,"startAnimation");
    		if (popupWindow == null) {
    			Log.d(TAG,"startAnimation(),new popupWindow now");
    			popupWindow = new PopupWindow(mViewArray.get(selectPosition), displayWidth, displayHeight);
    			popupWindow.setAnimationStyle(R.style.PopupWindowAnimation);
    			popupWindow.setFocusable(false);
    			popupWindow.setOutsideTouchable(true);
    		}
    		Log.d(TAG,"startAnimation(),selectedButton:"+selectedButton+",isChecked:"+selectedButton.isChecked()+
    				",popupWindow.isShowing:"+popupWindow.isShowing());
    		if (selectedButton.isChecked()) {
    
    			if (!popupWindow.isShowing()) {
    				showPopup(selectPosition);
    			} else {
    				popupWindow.setOnDismissListener(this);
    				popupWindow.dismiss();
    				hideView();
    			}
    		} else {
    			if (popupWindow.isShowing()) {
    				popupWindow.dismiss();
    				hideView();
    			}
    		}
    	}
    
    	private void showPopup(int position) {
    		View tView = mViewArray.get(selectPosition).getChildAt(0);
    		if (tView instanceof ViewBaseAction) {
    			ViewBaseAction f = (ViewBaseAction) tView;
    			f.show();
    		}
    		if (popupWindow.getContentView() != mViewArray.get(position)) {
    			popupWindow.setContentView(mViewArray.get(position));
    		}
    		popupWindow.showAsDropDown(this, 0, 0);
    	}
    
    	/**
    	 * 假如菜单成展开状态,则让菜单收回去
    	 */
    	public boolean onPressBack() {
    		Log.d(TAG,"onPressBack");
    		if (popupWindow != null && popupWindow.isShowing()) {
    			popupWindow.dismiss();
    			hideView();
    			if (selectedButton != null) {
    				selectedButton.setChecked(false);
    			}
    			return true;
    		} else {
    			return false;
    		}
    
    	}
    
    	private void hideView() {
    		Log.d(TAG, "hide()");
    		View tView = mViewArray.get(selectPosition).getChildAt(0);
    		if (tView instanceof ViewBaseAction) {
    			ViewBaseAction f = (ViewBaseAction) tView;
    			f.hide();
    		}
    	}
    
    	private void init(Context context) {
    		mContext = context;
    		displayWidth = ((Activity) mContext).getWindowManager().getDefaultDisplay().getWidth();
    		displayHeight = ((Activity) mContext).getWindowManager().getDefaultDisplay().getHeight();
    		setOrientation(LinearLayout.HORIZONTAL);
    	}
    
    	@Override
    	public void onDismiss() {
    		Log.d(TAG,"onDismiss,selectPosition:"+selectPosition);
    		showPopup(selectPosition);
    		popupWindow.setOnDismissListener(null);
    	}
    
    	private OnButtonClickListener mOnButtonClickListener;
    
    	/**
    	 * 设置tabitem的点击监听事件
    	 */
    	public void setOnButtonClickListener(OnButtonClickListener l) {
    		mOnButtonClickListener = l;
    	}
    
    	/**
    	 * 自定义tabitem点击回调接口
    	 */
    	public interface OnButtonClickListener {
    		public void onClick(int selectPosition);
    	}
    
    }

    5、ViewLeft

    其中的一个示例,其他两个就不列举了

    package com.example.view;
    
    import com.example.adapter.TextAdapter;
    import com.example.expandtabview.R;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.widget.ListView;
    import android.widget.RelativeLayout;
    import android.widget.Toast;
    
    public class ViewLeft extends RelativeLayout implements ViewBaseAction{
    	private static final String TAG = "ViewLeft";
    	private ListView mListView;
    	private final String[] items = new String[] { "item1", "item2", "item3", "item4", "item5", "item6" };//显示字段
    	private final String[] itemsVaule = new String[] { "1", "2", "3", "4", "5", "6" };//隐藏id
    	private OnSelectListener mOnSelectListener;
    	private TextAdapter adapter;
    	private String mDistance;
    	private String showText = "item1";
    	private Context mContext;
    
    	public String getShowText() {
    		return showText;
    	}
    
    	public ViewLeft(Context context) {
    		super(context);
    		init(context);
    	}
    
    	public ViewLeft(Context context, AttributeSet attrs, int defStyle) {
    		super(context, attrs, defStyle);
    		init(context);
    	}
    
    	public ViewLeft(Context context, AttributeSet attrs) {
    		super(context, attrs);
    		init(context);
    	}
    
    	private void init(Context context) {
    		mContext = context;
    		LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    		inflater.inflate(R.layout.view_distance, this, true);
    		setBackgroundDrawable(getResources().getDrawable(R.drawable.choosearea_bg_mid));
    		mListView = (ListView) findViewById(R.id.listView);
    		adapter = new TextAdapter(context, items, R.drawable.choose_item_right, R.drawable.choose_eara_item_selector);
    		adapter.setTextSize(17);
    		if (mDistance != null) {
    			for (int i = 0; i < itemsVaule.length; i++) {
    				if (itemsVaule[i].equals(mDistance)) {
    					adapter.setSelectedPositionNoNotify(i);
    					showText = items[i];
    					break;
    				}
    			}
    		}
    		mListView.setAdapter(adapter);
    		adapter.setOnItemClickListener(new TextAdapter.OnItemClickListener() {
    
    			@Override
    			public void onItemClick(View view, int position) {
    
    				if (mOnSelectListener != null) {
    					showText = items[position];
    					mOnSelectListener.getValue(itemsVaule[position], items[position]);
    				}
    			}
    		});
    	}
    
    	public void setOnSelectListener(OnSelectListener onSelectListener) {
    		mOnSelectListener = onSelectListener;
    	}
    
    	public interface OnSelectListener {
    		public void getValue(String distance, String showText);
    	}
    
    	@Override
    	public void hide() {
    
    	}
    
    	@Override
    	public void show() {
    
    	}
    
    }

    6,效果图

    好,今天就到这里。。希望有用。

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    正版 Windows 11产品密钥怎么查找/查看?

    还有3个月,微软将停止 Windows 10 的更新

    Windows 10 终止支持后,企业为何要立即升级?

    Windows 10 将于 2025年10 月终止技术支持,建议迁移到 Windows 11

    Windows 12 发布推迟,微软正全力筹备Windows 11 25H2更新

    Linux 退出 mail的命令是什么

    Linux 提醒 No space left on device,但我的空间看起来还有不少空余呢

    hiberfil.sys文件可以删除吗?了解该文件并手把手教你删除C盘的hiberfil.sys文件

    Window 10和 Windows 11哪个好?答案是:看你自己的需求

    盗版软件成公司里的“隐形炸弹”?老板们的“法务噩梦” 有救了!

    IT头条

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    液冷服务器概念股走强,博汇、润泽等液冷概念股票大涨

    01:17

    亚太地区的 AI 驱动型医疗保健:2025 年及以后的下一步是什么?

    16:30

    智能手机市场风云:iPhone领跑销量榜,华为缺席引争议

    15:43

    大数据算法和“老师傅”经验叠加 智慧化收储粮食尽显“科技范”

    15:17

    技术热点

    SQL汉字转换为拼音的函数

    windows 7系统无法运行Photoshop CS3的解决方法

    巧用MySQL加密函数对Web网站敏感数据进行保护

    MySQL基础知识简介

    Windows7和WinXP下如何实现不输密码自动登录系统的设置方法介绍

    windows 7系统ip地址冲突怎么办?windows 7系统IP地址冲突问题的

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。