DropDownMenu下拉菜单

来源:互联网 发布:nba2k16郭艾伦捏脸数据 编辑:程序博客网 时间:2024/05/16 06:46

最近项目要用到一个下拉菜单的功能,网上找了个例子http://www.jcodecraeer.com/a/opensource/2016/0110/3855.html,发现用起来不太方便,这个例子的内容区是外部addview进去的,不好控制实时刷新页面的情况,对控件操作也比较麻烦。然后自己就把别人的例子拿过来修改了一下,就可以在xml里面直接编写UI使用了,使用起来就方便了很多。

请尊重作者劳动成果,转载请标明原文地址:

http://blog.csdn.net/u010053224/article/details/51179251

1,使用预览

<pre name="code" class="html"><com.hyg.dropdownmenu.DropDownMenu    android:id="@+id/dropDownMenu"    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="match_parent"    app:dddividerColor="@color/gray"    app:ddmaskColor="@color/mask_color"    app:ddmenuBackgroundColor="@color/white"    app:ddmenuSelectedIcon="@mipmap/drop_down_selected_icon"    app:ddmenuIconToRight="true"    app:ddmenuTextSize="13sp"    app:ddmenuUnselectedIcon="@mipmap/drop_down_unselected_icon"    app:ddtextSelectedColor="@color/drop_down_selected"    app:ddtextUnselectedColor="@color/drop_down_unselected"    app:ddunderlineColor="@color/gray"    >    <TextView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_below="@id/dropDownMenu_underLine"        android:clickable="true"        android:gravity="center"        android:text="demo"        android:textSize="40sp"/></com.hyg.dropdownmenu.DropDownMenu>

只需xml只需简单添加如上代码,必须在
com.hyg.dropdownmenu.DropDownMenu的最外层添加android:layout_below="@id/dropDownMenu_underLine"添加这一行代码,否则内容区会有一部分被顶部菜单覆盖了,这个id名字是在ids里面写死的。 
效果如下图,图片也是从那个例子拿过来的,感谢原作者dongjunkun。

2,代码分析

能在xml里面添加内容的主要原因是id必须预先写好,使在布局时在xml里面能调用java代码编写的控件,因此在资源文件夹新建一个ids的文件夹写死几个id名字。
<?xml version="1.0" encoding="utf-8"?><resources>    <item name="dropDownMenu_tabMenuView" type="id"></item>    <item name="dropDownMenu_underLine" type="id"></item></resources>

菜单列表是从上往下弹出来的,为了能显示从菜单底部弹出列表,菜单就必须在顶层,这里说的菜单是上面图片最上一行的菜单,采用removeViewaddView的方法使菜单置于顶层会有些问题,因为remove后,前面与其为参照物的控件的位置就失效了,所以我在底部放置一个view,只要view的高度和菜单栏的高度一样就行了。如果是在dropdownmenu的java文件里面对xml的控件的位置采用 addRule重新设置的,不能显示实时更新,必须要调用 requestLayout方法才可以
//初始化tabMenuView并添加到tabMenuView的参照物tabMenuViewButtom = new LinearLayout(context);tabMenuViewButtom.setId(R.id.dropDownMenu_tabMenuView);LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);addView(tabMenuViewButtom,0);
这写代码就是那个底部的view。,

3,直接上最关键的代码。

package com.hyg.dropdownmenu;import android.content.Context;import android.content.res.TypedArray;import android.support.annotation.NonNull;import android.text.TextUtils;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.util.TypedValue;import android.view.Gravity;import android.view.View;import android.view.ViewGroup;import android.view.animation.AnimationUtils;import android.widget.FrameLayout;import android.widget.LinearLayout;import android.widget.RelativeLayout;import android.widget.TextView;import java.util.List;/** * 使用时,在这个布局最外层的view添加android:layout_below="@id/dropDownMenu_underLine"这一行代码。 * Created by HuangYuGuang on 2016/4/14. */public class DropDownMenu extends RelativeLayout {    //底层参照物控件,作为其他控件布局时候的相对参照    private LinearLayout tabMenuViewButtom;    //顶部菜单布局    private LinearLayout tabMenuView;    //底部容器,包含popupMenuViews,maskView    private View containerView;    //弹出菜单父布局    private FrameLayout popupMenuViews;    //遮罩半透明View,点击可关闭DropDownMenu    private View maskView;    //tabMenuView里面选中的tab位置,-1表示未选中    private int current_tab_position = -1;    //分割线颜色    private int dividerColor = 0xffcccccc;    //tab选中颜色    private int textSelectedColor = 0xff890c85;    //tab未选中颜色    private int textUnselectedColor = 0xff111111;    //遮罩颜色    private int maskColor = 0x88888888;    //tab字体大小    private int menuTextSize = 14;    //tab选中图标    private int menuSelectedIcon;    //tab未选中图标    private int menuUnselectedIcon;    //菜单背景色    private int menuBackgroundColor = 0xffffffff;    //菜单下面的分割线颜色    private int underlineColor = 0xffcccccc;    //菜单的箭头是否靠右边    private boolean menuIconToRight = false;    public DropDownMenu(Context context) {        super(context, null);    }    public DropDownMenu(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public DropDownMenu(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        //为DropDownMenu添加自定义属性        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DropDownMenu);        underlineColor = a.getColor(R.styleable.DropDownMenu_ddunderlineColor, underlineColor);        dividerColor = a.getColor(R.styleable.DropDownMenu_dddividerColor, dividerColor);        textSelectedColor = a.getColor(R.styleable.DropDownMenu_ddtextSelectedColor, textSelectedColor);        textUnselectedColor = a.getColor(R.styleable.DropDownMenu_ddtextUnselectedColor, textUnselectedColor);        menuBackgroundColor = a.getColor(R.styleable.DropDownMenu_ddmenuBackgroundColor, menuBackgroundColor);        maskColor = a.getColor(R.styleable.DropDownMenu_ddmaskColor, maskColor);        menuTextSize = a.getDimensionPixelSize(R.styleable.DropDownMenu_ddmenuTextSize, menuTextSize);        menuSelectedIcon = a.getResourceId(R.styleable.DropDownMenu_ddmenuSelectedIcon, menuSelectedIcon);        menuUnselectedIcon = a.getResourceId(R.styleable.DropDownMenu_ddmenuUnselectedIcon, menuUnselectedIcon);        menuIconToRight = a.getBoolean(R.styleable.DropDownMenu_ddmenuIconToRight, menuIconToRight);        a.recycle();        //初始化tabMenuView并添加到tabMenuView的参照物        tabMenuViewButtom = new LinearLayout(context);        tabMenuViewButtom.setId(R.id.dropDownMenu_tabMenuView);        LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);        addView(tabMenuViewButtom,0);        //为tabMenuView添加下划线        View underLine = new View(getContext());        underLine.setId(R.id.dropDownMenu_underLine);        LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1);        lp.addRule(RelativeLayout.BELOW, R.id.dropDownMenu_tabMenuView);        underLine.setLayoutParams(lp);        underLine.setBackgroundColor(underlineColor);        addView(underLine, 1);    }    /**     * 初始化DropDownMenu     *     * @param tabTexts     * @param popupViews     */    public void setDropDownMenu(@NonNull List<String> tabTexts, @NonNull List<View> popupViews) {        if (tabTexts.size() != popupViews.size()) {            throw new IllegalArgumentException("params not match, tabTexts.size() should be equal popupViews.size()");        }        LayoutParams plp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);        plp.addRule(RelativeLayout.BELOW, R.id.dropDownMenu_underLine);        maskView = new View(getContext());        maskView.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));        maskView.setBackgroundColor(maskColor);        maskView.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                closeMenu();            }        });        maskView.setVisibility(GONE);        maskView.setLayoutParams(plp);        addView(maskView);        popupMenuViews = new FrameLayout(getContext());        popupMenuViews.setVisibility(GONE);        popupMenuViews.setLayoutParams(plp);        addView(popupMenuViews);        for (int i = 0; i < popupViews.size(); i++) {            popupViews.get(i).setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));            popupMenuViews.addView(popupViews.get(i), i);        }        //初始化tabMenuView并添加到tabMenuView,为了能tabMenuView使位于顶层,所以最后添加tabMenuView        tabMenuView = new LinearLayout(getContext());        tabMenuView.setId(R.id.dropDownMenu_tabMenuView);        LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);        tabMenuView.setOrientation(LinearLayout.HORIZONTAL);        tabMenuView.setBackgroundColor(menuBackgroundColor);        tabMenuView.setLayoutParams(params);        addView(tabMenuView);        for (int i = 0; i < tabTexts.size(); i++) {            addTab(tabTexts, i);        }        //为了使tabMenuViewButtom和tabMenuView的高度一样        LayoutParams tparams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,tabMenuView.getHeight());        tabMenuViewButtom.setLayoutParams(tparams);    }    private void addTab(@NonNull List<String> tabTexts, int i) {        final TextView tab = new TextView(getContext());        LinearLayout menuItenmView = new LinearLayout(getContext());        menuItenmView.setLayoutParams(new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f));        menuItenmView.setGravity(Gravity.CENTER);        menuItenmView.setOrientation(LinearLayout.HORIZONTAL);        tab.setSingleLine();        tab.setEllipsize(TextUtils.TruncateAt.END);        tab.setGravity(Gravity.CENTER);        tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, menuTextSize);        if(menuIconToRight)            tab.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));        else            tab.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));        tab.setTextColor(textUnselectedColor);        tab.setCompoundDrawablesWithIntrinsicBounds(null, null, getResources().getDrawable(menuUnselectedIcon), null);        tab.setText(tabTexts.get(i) + "  ");        tab.setPadding(dpTpPx(5), dpTpPx(8), dpTpPx(5), dpTpPx(8));        menuItenmView.addView(tab, 0);        //添加点击事件        menuItenmView.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                switchMenu(tab);            }        });        tabMenuView.addView(menuItenmView);        //添加分割线        if (i < tabTexts.size() - 1) {            View view = new View(getContext());            view.setLayoutParams(new LayoutParams(dpTpPx(0.5f), ViewGroup.LayoutParams.MATCH_PARENT));            view.setBackgroundColor(dividerColor);            tabMenuView.addView(view);        }    }    /**     * 改变tab文字     *     * @param text     */    public void setTabText(String text) {        if (current_tab_position != -1) {            ((TextView) ((ViewGroup)tabMenuView.getChildAt(current_tab_position)).getChildAt(0)).setText(text+"  ");        }    }    public void setTabClickable(boolean clickable) {        for (int i = 0; i < tabMenuView.getChildCount(); i = i + 2) {            tabMenuView.getChildAt(i).setClickable(clickable);        }    }    /**     * 关闭菜单     */    public void closeMenu() {        if (current_tab_position != -1) {            TextView tab = (TextView) ((ViewGroup)tabMenuView.getChildAt(current_tab_position)).getChildAt(0);            tab.setTextColor(textUnselectedColor);            tab.setCompoundDrawablesWithIntrinsicBounds(null, null,                    getResources().getDrawable(menuUnselectedIcon), null);            popupMenuViews.setVisibility(View.GONE);            popupMenuViews.setAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.dd_menu_out));            maskView.setVisibility(GONE);            maskView.setAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.dd_mask_out));            current_tab_position = -1;        }    }    /**     * DropDownMenu是否处于可见状态     *     * @return     */    public boolean isShowing() {        return current_tab_position != -1;    }    /**     * 切换菜单     *     * @param target     */    private void switchMenu(View target) {        System.out.println(current_tab_position);        for (int i = 0; i < tabMenuView.getChildCount(); i = i + 2) {            TextView tab = (TextView) ((ViewGroup)tabMenuView.getChildAt(i)).getChildAt(0);            if (target == tab) {                if (current_tab_position == i) {                    closeMenu();                } else {                    if (current_tab_position == -1) {                        popupMenuViews.setVisibility(View.VISIBLE);                        popupMenuViews.setAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.dd_menu_in));                        maskView.setVisibility(VISIBLE);                        maskView.setAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.dd_mask_in));                        View view = popupMenuViews.getChildAt(i / 2);                        popupMenuViews.getChildAt(i / 2).setVisibility(View.VISIBLE);                    } else {                        popupMenuViews.getChildAt(i / 2).setVisibility(View.VISIBLE);                    }                    current_tab_position = i;                    tab.setTextColor(textSelectedColor);                    tab.setCompoundDrawablesWithIntrinsicBounds(null, null,                            getResources().getDrawable(menuSelectedIcon), null);                }            } else {                tab.setTextColor(textUnselectedColor);                tab.setCompoundDrawablesWithIntrinsicBounds(null, null,                        getResources().getDrawable(menuUnselectedIcon), null);                popupMenuViews.getChildAt(i / 2).setVisibility(View.GONE);            }        }    }    public int dpTpPx(float value) {        DisplayMetrics dm = getResources().getDisplayMetrics();        return (int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, dm) + 0.5);    }}

4,改进

模块经过项目的反复使用过程,又改进了一些,时使用起来更方便快捷了。XML里不用变,java文件了只需添加下面这段代码即可完成菜单的添加。
<pre name="code" class="java">mDropDownMenu1 = (DropDownMenu) findViewById(R.id.dropDownMenu1);DropDownMenuUtils.addTextList(this, mDropDownMenu1, new DropDownMenuUtils.OnMenuClickListener() {            @Override            public void onMenuClick(int viewPosition, int itemPosition) {                textView.setText(viewPosition+"---"+itemPosition);            }        }, Arrays.asList("全部", "衣服","鞋子"),Arrays.asList("默认排序","升序","降序"),Arrays.asList("好评","差评"));


如有还能改进的请大神在评论里面说一下。

              点击下载源码


      改进版源码

1 0
原创粉丝点击