亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

iOS的客戶端菜單功能仿百度糯米/美團二級菜單

2020-07-26 03:06:48
字體:
來源:轉載
供稿:網友

我剛好最近在開發一個商城項目,實現了一個簡單的控件,就和大家一起分享一下。

控件的效果就是類似百度糯米或者美團的二級菜單,我開發iOS的客戶端菜單功能,直接參考了git一個項目,對應的UI效果:

其實效果看起來還不錯。iOS開發完成以后,又要準備開發Android,發現對應網上的案例還是很少的,或者不是想要的效果。我想參考了別人的項目代碼,也為開源項目做點貢獻,準備自己開發一個Android的menu項目;

折騰了大概三個小時,終于搞定了,效果如下:

從圖片不難看出,這是一個多級菜單,控制者填充數據源,所以實現的時候,盡量封裝的使用,使用者最好是能兩三行代碼搞定。

具體實現思路:

1、MenuView,實現了第一級菜單的封裝

①、view初始化和數據源定義;

②、繪制一級菜單;

③、控制子菜單的PopupWindow彈出框

代碼具體如下:

package com.spring.sky.menuproject.view; import android.content.Context; import android.util.AttributeSet; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; import com.spring.sky.menuproject.AppInfoUtils; import com.spring.sky.menuproject.R; import java.util.List; /** * Created by springsky on 16/10/24. */ public class MenuView extends LinearLayout implements View.OnClickListener, MenuPopupWindow.OnMenuListener { private String[] hintTexts; public List[] dataSource; public TextView[] textViews; private int textColor = R.color.gray_80; private int textColorSelected = R.color.orange; private int textSize; private int lineHeight ; private MenuPopupWindow menuPopupWindow; private OnMenuListener onMenuListener; View lineView; TextView lastTv; private IndexPath[] indexPaths; public MenuView(Context context) { super(context); init(context); } public MenuView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public MenuView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } public void setHintTexts(String[] hintTexts) { this.hintTexts = hintTexts; } public void setDataSource(List[] dataSource) { this.dataSource = dataSource; reloadData(); } /*** * 設置當前選中的數據 * @param indexPath */ public void setIndexPath(IndexPath indexPath) { setIndexPath(indexPath, false); } /*** * 設置當前選中的內容 * @param indexPath * @param actionMenu 是否通知監聽器 */ public void setIndexPath(IndexPath indexPath, boolean actionMenu) { indexPaths[indexPath.column] = indexPath; if (actionMenu) { TextView lastTv = textViews[indexPath.column]; List<MenuModel> list = dataSource[indexPath.column]; if(list == null || indexPath.row >= list.size()){ return; } MenuModel left = list.get(indexPath.row); MenuModel menuModel = null; if (indexPath.item < 0) { menuModel = left; } else { MenuModel right = left.chindMenu.get(indexPath.item); menuModel = right; } lastTv.setText(menuModel.value); if (onMenuListener != null) { onMenuListener.onMenu(indexPath, menuModel); } } } public List[] getDataSource() { return dataSource; } /*** * 初始化 * @param context */ private void init(Context context) { menuPopupWindow = new MenuPopupWindow(context); menuPopupWindow.setOnMenuListener(this); AppInfoUtils.getViewHeight(this); textSize = AppInfoUtils.spToPx(6); lineHeight = AppInfoUtils.dipToPx(1); } /*** * 繪制一級菜單分類 */ private void reloadData() { removeAllViews(); if (dataSource == null || dataSource.length < 1) { return; } int count = dataSource.length; int height = getMeasuredHeight() - lineHeight; setOrientation(LinearLayout.VERTICAL); LinearLayout menuBaseView = new LinearLayout(getContext()); menuBaseView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, height)); menuBaseView.setWeightSum(count); menuBaseView.setGravity(Gravity.CENTER); menuBaseView.setOrientation(LinearLayout.HORIZONTAL); indexPaths = new IndexPath[count]; textViews = new TextView[count]; for (int i = 0; i < count; i++) { indexPaths[i] = new IndexPath(i, 0, -1); LinearLayout tempBaseView = new LinearLayout(getContext()); tempBaseView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, height, 1)); tempBaseView.setGravity(Gravity.CENTER); TextView tv = new TextView(getContext()); tv.setTextColor(getResources().getColor(textColor)); tv.setTextSize(textSize); LinearLayout.LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); tv.setGravity(Gravity.CENTER); tv.setLayoutParams(params); tv.setMaxLines(1); tv.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.mipmap.triangle_down, 0); tv.setCompoundDrawablePadding(AppInfoUtils.dipToPx(2)); tv.setId(i); tv.setOnClickListener(this); textViews[i] = tv; tempBaseView.addView(tv); menuBaseView.addView(tempBaseView); if (hintTexts != null && i < hintTexts.length) { tv.setText(hintTexts[i]); } View lineView = new View(getContext()); lineView.setBackgroundColor(getResources().getColor(R.color.main_bg_in)); menuBaseView.addView(lineView, new LayoutParams(AppInfoUtils.dipToPx(1), height - AppInfoUtils.dipToPx(8))); } addView(menuBaseView); lineView = new View(getContext()); lineView.setBackgroundColor(getResources().getColor(R.color.main_bg_in)); addView(lineView, new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, lineHeight)); } /*** * 一級菜單點擊事件觸發 * @param v */ @Override public void onClick(View v) { lastTv = (TextView) v; int column = v.getId(); List<MenuModel> list = dataSource[column]; lastTv.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.mipmap.triangle_up, 0); lastTv.setTextColor(getResources().getColor(textColorSelected)); menuPopupWindow.setLeftList(column, list); IndexPath indexPath = indexPaths[column]; menuPopupWindow.setSelect(indexPath.row, indexPath.item); // int[] location = new int[2]; // lineView.getLocationOnScreen(location); menuPopupWindow.showAsDropDown(lineView); // menuPopupWindow.showAtLocation(this,Gravity.BOTTOM,0,0); } /*** * 彈出框點擊事件處理 * @param column * @param row * @param item * @param menuModel */ @Override public void onMenu(int column, int row, int item, MenuModel menuModel) { TextView lastTv = textViews[column]; lastTv.setText(menuModel.value); IndexPath indexPath = indexPaths[column]; indexPath.row = row; indexPath.item = item; onMenuDismiss(); if (onMenuListener != null) { onMenuListener.onMenu(indexPath, menuModel); } } /*** * 彈出框關閉 */ @Override public void onMenuDismiss() { lastTv.setTextColor(getResources().getColor(R.color.gray_80)); lastTv.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.mipmap.triangle_down, 0); } /*** * 設置監聽器 * @param onMenuListener */ public void setOnMenuListener(OnMenuListener onMenuListener) { this.onMenuListener = onMenuListener; } public static interface OnMenuListener { void onMenu(IndexPath indexPath, MenuModel menuModel); } /**** * 菜單列、行、二級子行 */ public static class IndexPath { public int column; //一級菜單 public int row; //left row public int item; //right row public IndexPath(int column, int row, int item) { this.column = column; this.row = row; this.item = item; } } }

2、PopupWIndow主要是實現了彈出框顯示子列的一級和二級菜單的數據。

我使用了兩個ListView來動態實現數據的加載。

具體代碼如下:

package com.spring.sky.menuproject.view; import android.content.Context; import android.graphics.drawable.PaintDrawable; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.AdapterView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.PopupWindow; import com.spring.sky.menuproject.R; import java.util.List; /** * Created by springsky on 16/10/20. */ public class MenuPopupWindow extends PopupWindow implements AdapterView.OnItemClickListener { Context mContext; private ListView leftLv,rightLv; private OnMenuListener onMenuListener; private List<MenuModel> leftList,rightList; private MenuAdapter menuLeftAdapter,menuRightAdapter; private int column; boolean hasSecond; /*** * 初始化 * @param context */ public MenuPopupWindow(Context context){ this.mContext = context; View view = LayoutInflater.from(mContext).inflate(R.layout.menu_popup_window, null); leftLv = (ListView) view.findViewById(R.id.leftLv); leftLv.setChoiceMode(ListView.CHOICE_MODE_SINGLE); rightLv = (ListView) view.findViewById(R.id.rightLv); rightLv.setChoiceMode(ListView.CHOICE_MODE_SINGLE); setContentView(view); setBackgroundDrawable(new PaintDrawable()); setFocusable(true); setWidth(ViewGroup.LayoutParams.MATCH_PARENT); setHeight(LinearLayout.LayoutParams.WRAP_CONTENT); setOnDismissListener(new PopupWindow.OnDismissListener() { @Override public void onDismiss() { leftLv.setSelection(0); rightLv.setSelection(0); if( onMenuListener != null ){ onMenuListener.onMenuDismiss(); } } }); menuLeftAdapter = new MenuAdapter(mContext); menuLeftAdapter.setColumn(0); menuLeftAdapter.setList(leftList); leftLv.setAdapter(menuLeftAdapter); leftLv.setOnItemClickListener(this); menuRightAdapter = new MenuAdapter(mContext); menuRightAdapter.setColumn(1); menuRightAdapter.setList(rightList); rightLv.setAdapter(menuRightAdapter); rightLv.setOnItemClickListener(this); } @Override public void showAsDropDown(View anchor) { super.showAsDropDown(anchor); } /*** * 加載數據 * @param column * @param leftList */ public void setLeftList(int column,List<MenuModel> leftList) { this.column = column; this.leftList = leftList; hasSecond = false; for (MenuModel childModel : leftList){ if(childModel.hasChind()){ hasSecond = true; break; } } menuLeftAdapter.setList(leftList); if(!hasSecond){ rightLv.setVisibility(View.GONE); setRightList(null); }else { rightLv.setVisibility(View.VISIBLE); } } /*** * 默認選中的一級和二級行 * @param row * @param item */ public void setSelect(int row,int item){ if(row < 0 || leftList == null || row >= leftList.size()){ return; } MenuModel leftModel = leftList.get(row); leftLv.setSelection(row); menuLeftAdapter.setSelectPosition(row); setRightList(leftModel.chindMenu); if(item < 0 || rightList ==null || item >= rightList.size()){ return; } rightLv.setSelection(item); menuRightAdapter.setSelectPosition(item); } private void setRightList(List<MenuModel> rightList) { this.rightList = rightList; menuRightAdapter.setList(rightList); } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if(parent.getId() == leftLv.getId()){ MenuModel model = leftList.get(position); if(leftLv.getSelectedItemPosition() == position){ return; } if(model.hasChind()){ menuLeftAdapter.setSelectPosition(position); setRightList(model.chindMenu); }else { dismiss(); } onMenuClick(position,0,model); }else { menuRightAdapter.setSelectPosition(position); MenuModel model = rightList.get(position); onMenuClick(menuLeftAdapter.getSelectPosition(),position,model); dismiss(); } } void onMenuClick(int row,int item,MenuModel model){ if(onMenuListener != null){ onMenuListener.onMenu(column,row,item,model); } } public void setOnMenuListener(OnMenuListener onMenuListener) { this.onMenuListener = onMenuListener; } public static interface OnMenuListener{ void onMenu(int column, int row, int item, MenuModel menuModel); void onMenuDismiss(); } }

3、其他的就是MenuModel,考慮是多級層次關系,所以建議使用鏈結構。

package com.spring.sky.menuproject.view; import java.util.List; /** * Created by springsky on 16/10/20. */ public class MenuModel { public Object key; //key public String value; //顯示的內容 public List<MenuModel> chindMenu; //子列表數據 public MenuModel(){ super(); } public MenuModel(Object key, String value, List<MenuModel> chindMenu){ super(); this.key = key; this.value = value; this.chindMenu = chindMenu; } /*** * 是否有子列表數據 * @return */ public boolean hasChind(){ return (chindMenu != null && chindMenu.size() > 0); } }

誒,生活壓力大了,也不會寫博客了,就簡單描述一下,希望大家不要見怪。

項目的源碼,我已經提交到git上了。

下載地址:https://github.com/skyfouk/AndroidMenuProject.git

以上所述是小編給大家介紹的iOS的客戶端菜單功能仿百度糯米/美團二級菜單,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩在线视频网| 国产日韩欧美在线播放| 色无极亚洲影院| 久久精品欧美视频| 亚洲综合国产精品| 国产精品福利在线观看| 国产精品一区二区性色av| 92裸体在线视频网站| 亚洲综合国产精品| 欧美俄罗斯性视频| 久久久久久高潮国产精品视| 最新日韩中文字幕| 精品中文视频在线| 这里只有精品丝袜| 久久九九全国免费精品观看| 亚洲国产精品中文| 亚洲淫片在线视频| 国产亚洲视频中文字幕视频| 九九热这里只有精品6| 国产成人av在线| 中文日韩电影网站| 91影院在线免费观看视频| 久久综合免费视频| 精品中文字幕在线2019| 中文欧美在线视频| 久久久伊人日本| 精品magnet| 久久久久久久999| 成人激情在线观看| 亚洲人成77777在线观看网| 97欧美精品一区二区三区| 九九热精品视频| 国语自产精品视频在线看一大j8| 国产第一区电影| 97婷婷大伊香蕉精品视频| 亚洲欧美日韩一区在线| 国产日韩欧美一二三区| 91精品视频网站| 欧美精品在线免费| 在线精品播放av| 欧美激情va永久在线播放| 伊人久久大香线蕉av一区二区| 成人444kkkk在线观看| 国产精品日日摸夜夜添夜夜av| 91黄色8090| 国产精品美女www爽爽爽视频| 中文字幕亚洲在线| 亚洲欧美www| 精品亚洲一区二区三区| 亚洲国产欧美日韩精品| 中文字幕亚洲国产| 欧美日韩亚洲一区二区| 亚洲成人激情在线| 亚洲精品自在久久| 欧美一级大胆视频| 日韩av在线免费观看| 久久久精品在线观看| 色综合久久精品亚洲国产| 亚洲第一精品久久忘忧草社区| 欧美一级视频一区二区| 国产一区二区三区丝袜| 中文字幕在线成人| 国模gogo一区二区大胆私拍| 91精品国产自产在线老师啪| 日韩精品福利在线| 欧美日韩国产丝袜美女| 欧美最顶级丰满的aⅴ艳星| 亚洲在线一区二区| 亚洲无限乱码一二三四麻| 中文字幕一区二区三区电影| 亚洲国产小视频在线观看| 久久亚洲国产精品成人av秋霞| 欧美成人激情在线| 久久99热这里只有精品国产| 91av视频在线免费观看| 国产精品观看在线亚洲人成网| 亚洲福利视频久久| 亚洲精品久久久久久久久久久久久| 欧美成人精品不卡视频在线观看| 精品久久久久久久久久久| 插插插亚洲综合网| 深夜精品寂寞黄网站在线观看| 国产精品免费小视频| 91九色单男在线观看| 成人午夜黄色影院| 欧美成人一二三| 久久手机免费视频| 色婷婷**av毛片一区| 久久精彩免费视频| 成人女保姆的销魂服务| 日韩av电影院| 色综合视频网站| 91禁国产网站| 日韩高清av一区二区三区| 国产精品一区二区女厕厕| 欧美孕妇孕交黑巨大网站| 欧美日韩国产91| 国产精品视频内| 一本色道久久综合亚洲精品小说| 国产精品亚洲一区二区三区| 97国产精品视频人人做人人爱| 日本韩国在线不卡| 色婷婷av一区二区三区久久| 全球成人中文在线| 欧美中文字幕视频| 欧美精品一区二区免费| 国产69精品久久久久9| 久久久人成影片一区二区三区观看| 亚洲成人中文字幕| 2019中文字幕在线免费观看| 国产成人综合一区二区三区| 午夜精品久久久久久久久久久久久| 日韩欧美在线视频日韩欧美在线视频| 欧美一级bbbbb性bbbb喷潮片| 黑人巨大精品欧美一区二区免费| 亚洲欧洲日产国产网站| 亚洲欧美日韩在线高清直播| 中文字幕av一区二区| 欧美野外wwwxxx| 亚洲国产成人精品一区二区| 午夜精品久久久久久久白皮肤| 欧美黑人视频一区| 日韩成人中文字幕在线观看| 日本精品一区二区三区在线| 国产一区二区三区视频免费| 久久久久久com| 亚洲毛茸茸少妇高潮呻吟| 一区二区欧美日韩视频| 亚洲欧美日韩第一区| 亚洲黄色www| 97在线视频观看| 在线成人中文字幕| 久久久人成影片一区二区三区观看| 欧美大学生性色视频| 中文字幕一区二区三区电影| 欧美性高跟鞋xxxxhd| 8050国产精品久久久久久| 国产综合在线视频| 久久99青青精品免费观看| 欧美性少妇18aaaa视频| 亚洲欧美日韩国产精品| 日韩精品一区二区三区第95| 国产成人精品久久亚洲高清不卡| 成人精品视频久久久久| 亚洲成人av中文字幕| 国产成+人+综合+亚洲欧美丁香花| 精品精品国产国产自在线| 亚洲精品v天堂中文字幕| 成人天堂噜噜噜| 日韩a**中文字幕| 国产suv精品一区二区三区88区| 欧美黑人极品猛少妇色xxxxx| 欧美电影免费观看电视剧大全| 91成品人片a无限观看| 欧美激情在线狂野欧美精品| 超碰日本道色综合久久综合| 久久久久国产精品免费| 欧美理论电影网| 色yeye香蕉凹凸一区二区av| 欧美激情国产日韩精品一区18| 韩剧1988免费观看全集| 国产欧美在线看| 亚洲社区在线观看| 亚洲精品成人久久久|