你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS的客戶端菜單功用仿百度糯米/美團二級菜單

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

編輯:IOS開發綜合

我剛好最近在開發一個商城項目,完成了一個復雜的控件,就和大家一同分享一下。

控件的效果就是相似百度糯米或許美團的二級菜單,我開發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的客戶端菜單功用仿百度糯米/美團二級菜單,希望對大家有所協助,假如大家有任何疑問請給我留言,本站會及時回復大家的。在此也十分感激大家對本站網站的支持!

【iOS的客戶端菜單功用仿百度糯米/美團二級菜單】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved