使用Dialog自定义菜单

    通常我们使用actionbar的话,可以使用overflow按钮弹出所需菜单;但是有时我们需要自定义布局或者自定义标题栏,这时如果想要达到overflow的按钮菜单效果,就可以使用Dialog去自定义菜单了。

    通常Dialog包括几个最基本的布局框架(标题栏、信息、按钮),而根据我们的需求,我们可以去除标题栏、按钮;中间的信息可以使用listview来显示菜单item;而使用的style样式如下:

<style name="DialogWithoutTitle" parent="@android:style/Theme.Dialog">
    <item name="android:windowFrame">@null</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:background">@null</item>
    <item name="android:windowBackground">@android:color/transparent</item>
</style>
    其中windowNoTitle---无标题以及windowBackground---无背景比较关键,否则就达不到我们需要的样式;

    后续我们就可以使用自定义布局了,其中主要代码片段如下:

/*当然这里我们也可以使用LayoutInflater加载需要的布局*/
private View createActionMenuView() {
    RelativeLayout parent = new RelativeLayout(mContext);
    DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
    int statusAndTitleHeight = mHeadLayoutHeight;
    RelativeLayout.LayoutParams parentParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    parent.setLayoutParams(parentParams);
    parent.setBackgroundColor(mContext.getResources().getColor(R.color.background_primary));

    WindowManager.LayoutParams localLayoutParams = getWindow().getAttributes();
    if (mIsShowDialogPartial) {
        localLayoutParams.gravity = Gravity.TOP;
        localLayoutParams.x = metrics.widthPixels / 2;
        localLayoutParams.y = statusAndTitleHeight;
    } else {
        localLayoutParams.gravity = Gravity.FILL_HORIZONTAL | Gravity.TOP;
    }

    getWindow().setAttributes(localLayoutParams);

    ListView list = new ListView(mContext);
    LayoutParams listParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    if (mIsShowDialogPartial) {
        listParams.width = metrics.widthPixels / 2;
    }

    list.setLayoutParams(listParams);

    fillAdapterData();

    setListAdapter(list);

    list.setDivider(mContext.getResources().getDrawable(R.drawable.hw_list_divider));

    parent.addView(list);

    parent.startAnimation(createTranslationInAnimation());
    list.startAnimation(createAlphaInAnimation());
    return parent;
}
    其中通过
WindowManager.LayoutParams localLayoutParams = getWindow().getAttributes();
获取到window并设置window属性;可以设置dialog出现的位置;startAnimation是设置dialog出现时候的动画效果。

    另外,我们需要dialog消失的时候,也添加相应的动画,可以重写Dismiss函数:

@Override
public void dismiss() {
    if (mCustomView.getAnimation() != null && mCustomView.getAnimation().hasStarted()) {
        return;
    }
    mCustomView.startAnimation(outAnimation);
}
    这里需要注意,不能在Dismiss中调用super.dismiss();否则设置的动画会不起作用,我们可以在动画结束的时候调用super.dismiss();

    其他的定义interface,实现回调什么的就不写了,直接贴源码:

package com.example.switchfragment;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.SimpleAdapter;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PopMenu extends Dialog {

    private static final int TRANSLATE_DURATION = 200;
    private static final int TRANSLATE_DURATION_NA = 1;

    private Context mContext;
    private int mHeadLayoutHeight;
    private boolean mIsShowDialogPartial;

    private String mTitle;
    private String mMessage;

    private Animation outAnimation;

    private View mCustomView;

    private DialogListClickListener mDialogListClickListener;

    private ArrayList<HashMap<String, Object>> mAdapterData = new ArrayList<HashMap<String, Object>>();

    private ArrayList<DialogListItem> mListItems = new ArrayList<DialogListItem>();

    public PopMenu(Context context) {
        super(context, R.style.MmsDialogWithoutTitle);
        mContext = context;
        setCanceledOnTouchOutside(true);
        outAnimation = createTranslationOutAnimation(true);
    }

    public PopMenu(Context context, int headHeight, boolean isShowPartial) {
        this(context);
        mHeadLayoutHeight = headHeight;
        mIsShowDialogPartial = isShowPartial;
    }

    public void addItem(int id, String title) {
        mListItems.add(new DialogListItem(id, title));
    }

    public int getItemCount() {
        return mListItems.size();
    }

    public void setEnable(int id, boolean isEnable) {
        for (DialogListItem item : mListItems) {
            if (id == item.mId) {
                item.mEnable = isEnable;
                break;
            }
        }
    }

    public int[] getIDList() {
        int size = mListItems.size();
        int[] IDList = new int[size];
        DialogListItem item = null;
        for (int i = 0; i < size; i++) {
            item = mListItems.get(i);
            IDList[i] = item.mId;
        }

        return IDList;
    }

    public void setTitle(String title) {
        mTitle = title;
    }

    public void setMessage(String message) {
        mMessage = message;
    }

    public void setCustomView(View view) {
        mCustomView = view;
    }

    public void showDialog() {
        if (mCustomView == null) {
            mCustomView = createActionMenuView();
        }
        setContentView(mCustomView);
        show();
    }

    @Override
    public void dismiss() {
        if (mCustomView.getAnimation() != null && mCustomView.getAnimation().hasStarted()) {
            return;
        }
        mCustomView.startAnimation(outAnimation);
    }

    private void onItemClickDismiss() {
        if (mCustomView.getAnimation() != null && mCustomView.getAnimation().hasStarted()) {
            return;
        }
        mCustomView.startAnimation(outAnimation);
    }

    private void internalDismiss() {
        super.dismiss();
    }

    private Animation createTranslationOutAnimation(boolean animation) {
        int type = TranslateAnimation.RELATIVE_TO_SELF;
        TranslateAnimation an = new TranslateAnimation(type, 0, type, 0, type, 0, type, -1);
        an.setDuration(animation ? TRANSLATE_DURATION : TRANSLATE_DURATION_NA);
        an.setFillAfter(true);
        an.setAnimationListener(new Animation.AnimationListener() {

            @Override
            public void onAnimationStart(Animation animation) {
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                internalDismiss();
            }
        });
        return an;
    }

    /*当然这里我们也可以使用LayoutInflater加载需要的布局*/
    private View createActionMenuView() {
        RelativeLayout parent = new RelativeLayout(mContext);
        DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
        int statusAndTitleHeight = mHeadLayoutHeight;
        RelativeLayout.LayoutParams parentParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        parent.setLayoutParams(parentParams);
        parent.setBackgroundColor(mContext.getResources().getColor(R.color.background_primary));

        WindowManager.LayoutParams localLayoutParams = getWindow().getAttributes();
        if (mIsShowDialogPartial) {
            localLayoutParams.gravity = Gravity.TOP;
            localLayoutParams.x = metrics.widthPixels / 2;
            localLayoutParams.y = statusAndTitleHeight;
        } else {
            localLayoutParams.gravity = Gravity.FILL_HORIZONTAL | Gravity.TOP;
        }

        getWindow().setAttributes(localLayoutParams);

        ListView list = new ListView(mContext);
        LayoutParams listParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        if (mIsShowDialogPartial) {
            listParams.width = metrics.widthPixels / 2;
        }

        list.setLayoutParams(listParams);

        fillAdapterData();

        setListAdapter(list);

        list.setDivider(mContext.getResources().getDrawable(R.drawable.hw_list_divider));

        parent.addView(list);

        parent.startAnimation(createTranslationInAnimation());
        list.startAnimation(createAlphaInAnimation());
        return parent;
    }

    private Animation createAlphaInAnimation() {
        AlphaAnimation an = new AlphaAnimation(0.0f, 1.0f);
        an.setDuration(TRANSLATE_DURATION);
        return an;
    }

    private Animation createTranslationInAnimation() {
        int type = TranslateAnimation.RELATIVE_TO_SELF;
        TranslateAnimation an = new TranslateAnimation(type, 0, type, 0, type, -1, type, 0);
        an.setDuration((TRANSLATE_DURATION));
        return an;
    }

    private int getStatusBarHeight(Activity activity) {
        if (activity == null) {
            return 0;
        }

        Rect rect = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
        int statusBarHeight = rect.top;
        return statusBarHeight;
    }

    private void fillAdapterData() {
        mAdapterData.clear();

        for (DialogListItem item : mListItems) {
            HashMap<String, Object> map = new HashMap<String, Object>(1);
            map.put("title", item.mTitle);
            mAdapterData.add(map);
        }
    }

    public void setListAdapter(ListView list) {
        DialogListAdapter adapter = new DialogListAdapter(mContext, mAdapterData, R.layout.dialog_list_item,
                new String[]{"title"}, new int[]{R.id.title});
        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                DialogListItem item = (DialogListItem) view.getTag();
                if (!item.mEnable) {
                    return;
                }
                if (mDialogListClickListener != null) {
                    mDialogListClickListener.onClick(item.mId);
                }
                onItemClickDismiss();
            }
        });
        list.setAdapter(adapter);
    }

    public interface DialogListClickListener {
        void onClick(int which);
    }

    public void setDialogListClickListener(DialogListClickListener l) {
        mDialogListClickListener = l;
    }

    private class DialogListItem {
        public int mId;
        public String mTitle;
        public boolean mEnable = true;

        public DialogListItem(int id, String title) {
            mId = id;
            mTitle = title;
        }
    }

    private class DialogListAdapter extends SimpleAdapter {


        public DialogListAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
            super(context, data, resource, from, to);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view = super.getView(position, convertView, parent);

            if (!mListItems.get(position).mEnable) {
                TextView title = (TextView) view.findViewById(R.id.title);
                title.setEnabled(false);
            }

            view.setTag(mListItems.get(position));

            return view;
        }

    }
}


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值