Android实现横向二级菜单
本文实例为大家分享了android二级横向菜单的实现过程.效果如上图:
这种横向的二级菜单在很多的app都有所应用.效果看起来还是非常的美观的.也算是项目需要,自己也就学了一下这个效果,首先说一下逻辑.实现的方式其实并不是很难..只不过逻辑上可能有点复杂.原理其实就是一个按钮.当触发按钮的时候弹出popwindow.popwindow由两个listview构成..对两个listview适当的适配.就可以实现这个效果了..
实现这种效果可以有两种不同的方式..一种是直接在布局文件layout.xml中写..最上方的可以是一个按钮.也可以是多个按钮..多个按钮就可以使用radiogroup去实现..下方则采用scrollview去实现也是可以的..
不过我还是说一下第二种方式..直接用java去写这个布局..通过使用自定义控件的方式实现这个效果..既然是自定义,那么首先我们需要继承一个布局.布局可以使用linearlayout或者relativelayout.
setvalue()方法..
setvalue()方法是自定义的方法..主要是用于加载布局.以及在布局当中添加相关的view.没有加载任何的xml文件..
/** * @param textarray: listview中item对应的text值的集合.. * @param viewarray: 当前layout中需要加入的view.. * */ @suppresslint("resourceascolor") public void setvalue(arraylist<string> textarray, arraylist<view> viewarray) { if (mcontext == null) { return; } layoutinflater inflater = (layoutinflater) mcontext.getsystemservice(context.layout_inflater_service); mtextlist = textarray; for (int i = 0; i < viewarray.size(); i++) { //这里就添加了一个view.. final relativelayout r = new relativelayout(mcontext); int maxheight = (int) (displayheight * 0.5); //定义布局的高度.. relativelayout.layoutparams rl = new relativelayout.layoutparams(relativelayout.layoutparams.match_parent, maxheight); r.addview(viewarray.get(i), rl); //在布局中添加view并指定参数 mviewlist.add(r); r.settag(small); //定义最上方的按钮,并在布局中添加这个按钮。并设置按钮的text togglebutton tbutton = (togglebutton) inflater.inflate(r.layout.toggle_button, this, false); addview(tbutton); mtogglelist.add(tbutton); tbutton.settag(i); tbutton.settext(mtextlist.get(i)); //用于实现当popwindow显示时.再次点击收回popwindow r.setonclicklistener(new onclicklistener() { @override public void onclick(view v) { onpressback(); } }); r.setbackgroundcolor(mcontext.getresources().getcolor(r.color.popup_main_background)); //当按钮被点击后需要触发的监听 tbutton.setonclicklistener(new onclicklistener() { @override public void onclick(view view) { 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); } } }); } }
那么设置完了布局的样式后..只有一个togglebutton按钮.点击后没有任何的效果.我们需要去定义一个新的view视图.用于点击按钮后需要显示的弹出窗.那么这个弹出窗也需要自定义..
弹出窗则采用两个listview的形式进行显示.在布局中将两个listview进行添加.对每一个listview设置相应的适配器.然后将这个view添加到上面的主view当中.就可以实现当button被点击后,弹出窗在下方进行显示的效果..
childview() 弹出窗view的布局实现方式..
这里定义了这个view,并完成相应的初始化操作.设置对应的适配器也就完成了..
package com.example.view; import java.util.arraylist; import java.util.linkedlist; import android.content.context; import android.util.attributeset; import android.util.sparsearray; import android.view.layoutinflater; import android.view.view; import android.widget.linearlayout; import android.widget.listview; import com.example.adapter.textadapter; import com.example.expandtabview.r; public class childview extends linearlayout { private listview regionlistview; //主listview private listview platelistview; //子listview //主listview每一个item对应的text private string leftfastring[] = new string[] { "美食", "快餐小吃", "火锅", "海鲜/烧烤", "特色菜", "香锅/烤鱼", "地方菜", "东南亚菜", "西餐", "日韩料理" }; //子listview每一个item对应的text..采用了二维数组的实现方式.. private string leftch1string[][] = new string[][] { { "全部" }, { "全部", "中式简餐", "地方小吃", "盖浇饭", "米粉米线", "面馆", "麻辣烫", "黄焖鸡米饭", "鸭脖卤味", "饺子馄饨", "炸鸡炸串", "包子/粥", "零食", "生煎锅贴", "冒菜" }, { "全部", "其他火锅" }, { "全部", "小龙虾" }, { "全部" }, { "全部", "香锅", "烤鱼" }, { "全部", "鲁菜", "川菜", "其他" }, { "全部" }, { "全部", "意面披萨", "西式快餐", "其他西餐" }, { "全部", "韩式简餐", "韩国料理" } }; //添加主listview中的数据信息 private arraylist<string> groups = new arraylist<string>(); //添加子listview中的数据信息 private linkedlist<string> childrenitem = new linkedlist<string>(); //稀疏数组 private sparsearray<linkedlist<string>> children = new sparsearray<linkedlist<string>>(); //为listview设置适配器 private textadapter platelistviewadapter; private textadapter earalistviewadapter; //监听事件的设置 private onselectlistener monselectlistener; private int tearaposition = 0; //用于保存当前主listview被点击的item对应的position. private int tblockposition = 0; //用于保存当前子listview被点击的item对应的position. private string showstring = ""; public childview(context context) { super(context); init(context); } public childview(context context, attributeset attrs) { super(context, attrs); init(context); } private void init(context context) { layoutinflater inflater = (layoutinflater) context .getsystemservice(context.layout_inflater_service); //加载布局,绑定id. inflater.inflate(r.layout.view_region, this, true); regionlistview = (listview) findviewbyid(r.id.listview); platelistview = (listview) findviewbyid(r.id.listview2); //初始化listview中每一个item对应的text for(int i=0;i<10;i++){ groups.add(leftfastring[i]); linkedlist<string> titem = new linkedlist<string>(); for(int j=0;j<leftch1string[i].length;j++){ titem.add(leftch1string[i][j]); } children.put(i, titem); } //主listview列表项的适配器 earalistviewadapter = new textadapter(context, groups, r.drawable.choose, r.drawable.choose_eara_item_selector); earalistviewadapter.settextsize(12); earalistviewadapter.setselectedpositionnonotify(tearaposition); regionlistview.setadapter(earalistviewadapter); earalistviewadapter .setonitemclicklistener(new textadapter.onitemclicklistener() { @override public void onitemclick(view view, int position) { if (position < children.size()) { childrenitem.clear(); //获取这一页的所有数据信息..然后唤醒适配器更新数据 childrenitem.addall(children.get(position)); platelistviewadapter.notifydatasetchanged(); } } }); if (tearaposition < children.size()) childrenitem.addall(children.get(tearaposition)); //子listview的适配器 platelistviewadapter = new textadapter(context, childrenitem, r.drawable.choose_item_right, r.drawable.choose_plate_item_selector); platelistviewadapter.settextsize(12); platelistviewadapter.setselectedpositionnonotify(tblockposition); platelistview.setadapter(platelistviewadapter); //设置当item被点击后触发的监听. platelistviewadapter .setonitemclicklistener(new textadapter.onitemclicklistener() { @override public void onitemclick(view view, final int position) { //获取被点击的item的文字数据 showstring = childrenitem.get(position); if (monselectlistener != null) { monselectlistener.getvalue(showstring); } } }); if (tblockposition < childrenitem.size()) showstring = childrenitem.get(tblockposition); setdefaultselect(); } //设置当前item的position. public void setdefaultselect() { //默认选择的item项 regionlistview.setselection(tearaposition); platelistview.setselection(tblockposition); } public string getshowtext() { return showstring; } public void setonselectlistener(onselectlistener onselectlistener) { monselectlistener = onselectlistener; } public interface onselectlistener { public void getvalue(string showtext); } }
那么最后就剩下适配器了..
arrayadapter<string>
这里使用了arrayadapter适配器.继承与baseadapter.可以用于显示文本数据..我们也都知道,适配器必须要实现的方法就是getview()方法了..那么我们就简单的看一下这个方法..
@suppresslint("resourceascolor") @suppresswarnings("deprecation") @override public view getview(int position, view convertview, viewgroup parent) { textview view; if (convertview == null) { view = (textview) layoutinflater.from(mcontext).inflate(r.layout.choose_item, parent, false); } else { view = (textview) convertview; } view.settag(position); string mstring = ""; if (mlistdata != null) { if (position < mlistdata.size()) { mstring = mlistdata.get(position); } } else if (marraydata != null) { if (position < marraydata.length) { mstring = marraydata[position]; } } if (mstring.contains("不限")) view.settext("不限"); else view.settext(mstring); view.settextsize(typedvalue.complex_unit_sp,textsize); if (selectedtext != null && selectedtext.equals(mstring)) { view.setbackgrounddrawable(selecteddrawble);//设置选中的背景图片 } else { view.setbackgrounddrawable(mcontext.getresources().getdrawable(normaldrawbleid));//设置未选中状态背景图片 } view.setpadding(20, 0, 0, 0); view.setonclicklistener(onclicklistener); return view; }
适配的工作还是非常的简单的.仅仅一个textview就可以搞定了.当然我们也可以写一个比较复杂的样式.在一个layout内部定义一些复杂的控件.就能够实现更好的效果.
最后再mainactivity中的布局文件中加载这个控件,简单的做一些初始化操作就可以实现了..
package com.example.expandtabview; import java.util.arraylist; import android.app.activity; import android.os.bundle; import android.view.view; import android.widget.toast; import com.example.view.expandtabview; import com.example.view.childview; public class mainactivity extends activity { private expandtabview expandtabview; private arraylist<view> mviewarray = new arraylist<view>(); private childview viewleft; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); initview(); initvaule(); initlistener(); } private void initview() { //初始化控件 expandtabview = (expandtabview) findviewbyid(r.id.expandtab_view); viewleft = new childview(this); } private void initvaule() { mviewarray.add(viewleft); //设置顶部数据信息 arraylist<string> mtextarray = new arraylist<string>(); mtextarray.add("全部"); expandtabview.setvalue(mtextarray, mviewarray); expandtabview.settitle(viewleft.getshowtext(), 0); } private void initlistener() { viewleft.setonselectlistener(new childview.onselectlistener() { @override public void getvalue(string showtext) { onrefresh(viewleft,showtext); } }); } //视图被点击后刷新数据 private void onrefresh(view view, string 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(); } //获取当前的view private int getpositon(view tview) { for (int i = 0; i < mviewarray.size(); i++) { if (mviewarray.get(i) == tview) { return i; } } return -1; } }
这里只是贴了一些核心代码.其他的涉及的一些不重要的代码就不在这里粘贴了..最后放一张图片流程.方便大家去理解.最后给出源代码.
放一个源代码提供下载,方便去理解这个过程:android实现横向二级菜单
以上就是本文的全部内容,希望对大家的学习有所帮助。