关闭 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,效果图

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

    上一篇返回首页 下一篇

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

    别人在看

    Destoon 模板存放规则及语法参考

    Destoon系统常量与变量

    Destoon系统目录文件结构说明

    Destoon 系统安装指南

    Destoon会员公司主页模板风格添加方法

    Destoon 二次开发入门

    Microsoft 将于 2026 年 10 月终止对 Windows 11 SE 的支持

    Windows 11 存储感知如何设置?了解Windows 11 存储感知开启的好处

    Windows 11 24H2 更新灾难:系统升级了,SSD固态盘不见了...

    小米路由器买哪款?Miwifi热门路由器型号对比分析

    IT头条

    Synology 对 Office 套件进行重大 AI 更新,增强私有云的生产力和安全性

    01:43

    StorONE 的高效平台将 Storage Guardian 数据中心占用空间减少 80%

    11:03

    年赚千亿的印度能源巨头Nayara 云服务瘫痪,被微软卡了一下脖子

    12:54

    国产6nm GPU新突破!砺算科技官宣:自研TrueGPU架构7月26日发布

    01:57

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

    02:03

    技术热点

    如何删除自带的不常用应用为windows 7减负

    MySQL中多表删除方法

    改进的二值图像像素标记算法及程序实现

    windows 7 32位系统下手动修改磁盘属性例如M盘修改为F盘

    windows 7中怎么样在家庭组互传文件

    Linux应用集成MySQL数据库访问技巧

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

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