欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android仿美团淘宝实现多级下拉列表菜单功能

程序员文章站 2024-03-31 11:17:28
我们在常用的电商或者旅游app中,例如美团,手机淘宝等等,都能够看的到有那种下拉式的二级列表菜单。具体如图所示: 上面两张图就是美团的一个二级列表菜单的一个展示。我相信很...

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

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

1.结构分析

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

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

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

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

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

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

2.项目结构

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

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

2)mainactivity。主活动页面。

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

4)viewleft,viewmiddle,viewright。是弹出里面嵌套的类,实现不同的列表菜单。

Android仿美团淘宝实现多级下拉列表菜单功能 

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 mviewarray = new arraylist(); 
  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 mtextarray = new arraylist(); 
    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 mtextarray = new arraylist(); 
  private arraylist mviewarray = new arraylist(); 
  private arraylist mtogglebutton = new arraylist(); 
  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 textarray, arraylist 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.效果图

Android仿美团淘宝实现多级下拉列表菜单功能 

Android仿美团淘宝实现多级下拉列表菜单功能

以上所述是小编给大家介绍的android仿美团淘宝实现多级下拉列表菜单功能,多条目的实例代码,希望对大家有所帮助