转载请注明出处:http://blog.csdn.net/bbld_/article/details/39124097
前言
这几天用到了github上的一个仿IOS的ActionSheet(ActionSheetForAndroid)控件,它是使用Fragment实现的,由于我的主界面也是由几个Fragment来做,所以这样会造成FragmentManager出现一些问题。所以就把它的实现方式改为由自定义Dialog来实现,保留它的主题属性方便修改样式,同时去除Fragmrnt部分,增加可用性。
实现
- package com.roc.actionsheet;
- import java.util.Arrays;
- import java.util.List;
- import android.app.Activity;
- import android.app.Dialog;
- import android.content.Context;
- import android.content.res.TypedArray;
- import android.graphics.Color;
- import android.graphics.drawable.ColorDrawable;
- import android.graphics.drawable.Drawable;
- import android.graphics.drawable.StateListDrawable;
- import android.util.TypedValue;
- import android.view.Gravity;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.ViewGroup.LayoutParams;
- import android.view.animation.AlphaAnimation;
- import android.view.animation.Animation;
- import android.view.animation.TranslateAnimation;
- import android.view.inputmethod.InputMethodManager;
- import android.widget.Button;
- import android.widget.FrameLayout;
- import android.widget.LinearLayout;
- /**
- * ActionSheet
- *
- * @author Mr.Zheng
- * @date 2014年9月7日 下午11:15:54
- */
- public class ActionSheet extends Dialog implements OnClickListener
- {
- /* 控件的id */
- private static final int CANCEL_BUTTON_ID = 100;
- private static final int BG_VIEW_ID = 10;
- private static final int TRANSLATE_DURATION = 300;
- private static final int ALPHA_DURATION = 300;
- private Context mContext;
- private Attributes mAttrs;
- private MenuItemClickListener mListener;
- private View mView;
- private LinearLayout mPanel;
- private View mBg;
- private List<String> items;
- private String cancelTitle = "";
- private boolean mCancelableOnTouchOutside;
- private boolean mDismissed = true;
- private boolean isCancel = true;
- public ActionSheet(Context context)
- {
- super(context, android.R.style.Theme_Light_NoTitleBar);// 全屏
- this.mContext = context;
- initViews();
- getWindow().setGravity(Gravity.BOTTOM);
- Drawable drawable = new ColorDrawable();
- drawable.setAlpha(0);// 设置透明背景
- getWindow().setBackgroundDrawable(drawable);
- }
- public void initViews()
- {
- /* 隐藏软键盘 */
- InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
- if (imm.isActive())
- {
- View focusView = ((Activity) mContext).getCurrentFocus();
- if (focusView != null)
- imm.hideSoftInputFromWindow(focusView.getWindowToken(), 0);
- }
- mAttrs = readAttribute();// 获取主题属性
- mView = createView();
- mBg.startAnimation(createAlphaInAnimation());
- mPanel.startAnimation(createTranslationInAnimation());
- }
- 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 Animation createAlphaInAnimation()
- {
- AlphaAnimation an = new AlphaAnimation(0, 1);
- an.setDuration(ALPHA_DURATION);
- return an;
- }
- private Animation createTranslationOutAnimation()
- {
- int type = TranslateAnimation.RELATIVE_TO_SELF;
- TranslateAnimation an = new TranslateAnimation(type, 0, type, 0, type, 0, type, 1);
- an.setDuration(TRANSLATE_DURATION);
- an.setFillAfter(true);
- return an;
- }
- private Animation createAlphaOutAnimation()
- {
- AlphaAnimation an = new AlphaAnimation(1, 0);
- an.setDuration(ALPHA_DURATION);
- an.setFillAfter(true);
- return an;
- }
- /**
- * 创建基本的背景视图
- */
- private View createView()
- {
- FrameLayout parent = new FrameLayout(mContext);
- FrameLayout.LayoutParams parentParams = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
- LayoutParams.MATCH_PARENT);
- parentParams.gravity = Gravity.BOTTOM;
- parent.setLayoutParams(parentParams);
- mBg = new View(mContext);
- mBg.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
- mBg.setBackgroundColor(Color.argb(136, 0, 0, 0));
- mBg.setId(BG_VIEW_ID);
- mBg.setOnClickListener(this);
- mPanel = new LinearLayout(mContext);
- FrameLayout.LayoutParams mPanelParams = new FrameLayout.LayoutParams(
- FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
- mPanelParams.gravity = Gravity.BOTTOM;
- mPanel.setLayoutParams(mPanelParams);
- mPanel.setOrientation(LinearLayout.VERTICAL);
- parent.addView(mBg);
- parent.addView(mPanel);
- return parent;
- }
- /**
- * 创建MenuItem
- */
- private void createItems()
- {
- if (items != null && items.size() > 0)
- for (int i = 0; i < items.size(); i++)
- {
- Button bt = new Button(mContext);
- bt.setId(CANCEL_BUTTON_ID + i + 1);
- bt.setOnClickListener(this);
- bt.setBackgroundDrawable(getOtherButtonBg(items.toArray(new String[items.size()]), i));
- bt.setText(items.get(i));
- bt.setTextColor(mAttrs.otherButtonTextColor);
- bt.setTextSize(TypedValue.COMPLEX_UNIT_PX, mAttrs.actionSheetTextSize);
- if (i > 0)
- {
- LinearLayout.LayoutParams params = createButtonLayoutParams();
- params.topMargin = mAttrs.otherButtonSpacing;
- mPanel.addView(bt, params);
- } else
- mPanel.addView(bt);
- }
- Button bt = new Button(mContext);
- bt.getPaint().setFakeBoldText(true);
- bt.setTextSize(TypedValue.COMPLEX_UNIT_PX, mAttrs.actionSheetTextSize);
- bt.setId(CANCEL_BUTTON_ID);
- bt.setBackgroundDrawable(mAttrs.cancelButtonBackground);
- bt.setText(cancelTitle);
- bt.setTextColor(mAttrs.cancelButtonTextColor);
- bt.setOnClickListener(this);
- LinearLayout.LayoutParams params = createButtonLayoutParams();
- params.topMargin = mAttrs.cancelButtonMarginTop;
- mPanel.addView(bt, params);
- mPanel.setBackgroundDrawable(mAttrs.background);
- mPanel.setPadding(mAttrs.padding, mAttrs.padding, mAttrs.padding, mAttrs.padding);
- }
- public LinearLayout.LayoutParams createButtonLayoutParams()
- {
- LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
- LayoutParams.WRAP_CONTENT);
- return params;
- }
- /**
- * item按钮的颜色
- *
- * @param titles
- * @param i
- * @return
- */
- private Drawable getOtherButtonBg(String[] titles, int i)
- {
- if (titles.length == 1)
- return mAttrs.otherButtonSingleBackground;
- else if (titles.length == 2)
- switch (i)
- {
- case 0:
- return mAttrs.otherButtonTopBackground;
- case 1:
- return mAttrs.otherButtonBottomBackground;
- }
- else if (titles.length > 2)
- {
- if (i == 0)
- return mAttrs.otherButtonTopBackground;
- else if (i == (titles.length - 1))
- return mAttrs.otherButtonBottomBackground;
- return mAttrs.getOtherButtonMiddleBackground();
- }
- return null;
- }
- public void showMenu()
- {
- if (!mDismissed)
- return;
- show();
- getWindow().setContentView(mView);
- mDismissed = false;
- }
- /**
- * dissmiss Menu菜单
- */
- public void dismissMenu()
- {
- if (mDismissed)
- return;
- dismiss();
- onDismiss();
- mDismissed = true;
- }
- /**
- * dismiss时的处理
- */
- private void onDismiss()
- {
- mPanel.startAnimation(createTranslationOutAnimation());
- mBg.startAnimation(createAlphaOutAnimation());
- }
- /**
- * 取消按钮的标题文字
- *
- * @param title
- * @return
- */
- public ActionSheet setCancelButtonTitle(String title)
- {
- this.cancelTitle = title;
- return this;
- }
- /**
- * 取消按钮的标题文字
- *
- * @param strId
- * @return
- */
- public ActionSheet setCancelButtonTitle(int strId)
- {
- return setCancelButtonTitle(mContext.getString(strId));
- }
- /**
- * 点击外部边缘是否可取消
- *
- * @param cancelable
- * @return
- */
- public ActionSheet setCancelableOnTouchMenuOutside(boolean cancelable)
- {
- mCancelableOnTouchOutside = cancelable;
- return this;
- }
- public ActionSheet addItems(String... titles)
- {
- if (titles == null || titles.length == 0)
- return this;
- items = Arrays.asList(titles);
- createItems();
- return this;
- }
- public ActionSheet setItemClickListener(MenuItemClickListener listener)
- {
- this.mListener = listener;
- return this;
- }
- private Attributes readAttribute()
- {
- Attributes attrs = new Attributes(mContext);
- TypedArray a = mContext.getTheme().obtainStyledAttributes(null, R.styleable.ActionSheet,
- R.attr.actionSheetStyle, 0);
- Drawable background = a.getDrawable(R.styleable.ActionSheet_actionSheetBackground);
- if (background != null)
- attrs.background = background;
- Drawable cancelButtonBackground = a.getDrawable(R.styleable.ActionSheet_cancelButtonBackground);
- if (cancelButtonBackground != null)
- attrs.cancelButtonBackground = cancelButtonBackground;
- Drawable otherButtonTopBackground = a.getDrawable(R.styleable.ActionSheet_otherButtonTopBackground);
- if (otherButtonTopBackground != null)
- attrs.otherButtonTopBackground = otherButtonTopBackground;
- Drawable otherButtonMiddleBackground = a
- .getDrawable(R.styleable.ActionSheet_otherButtonMiddleBackground);
- if (otherButtonMiddleBackground != null)
- attrs.otherButtonMiddleBackground = otherButtonMiddleBackground;
- Drawable otherButtonBottomBackground = a
- .getDrawable(R.styleable.ActionSheet_otherButtonBottomBackground);
- if (otherButtonBottomBackground != null)
- attrs.otherButtonBottomBackground = otherButtonBottomBackground;
- Drawable otherButtonSingleBackground = a
- .getDrawable(R.styleable.ActionSheet_otherButtonSingleBackground);
- if (otherButtonSingleBackground != null)
- attrs.otherButtonSingleBackground = otherButtonSingleBackground;
- attrs.cancelButtonTextColor = a.getColor(R.styleable.ActionSheet_cancelButtonTextColor,
- attrs.cancelButtonTextColor);
- attrs.otherButtonTextColor = a.getColor(R.styleable.ActionSheet_otherButtonTextColor,
- attrs.otherButtonTextColor);
- attrs.padding = (int) a.getDimension(R.styleable.ActionSheet_actionSheetPadding, attrs.padding);
- attrs.otherButtonSpacing = (int) a.getDimension(R.styleable.ActionSheet_otherButtonSpacing,
- attrs.otherButtonSpacing);
- attrs.cancelButtonMarginTop = (int) a.getDimension(R.styleable.ActionSheet_cancelButtonMarginTop,
- attrs.cancelButtonMarginTop);
- attrs.actionSheetTextSize = a.getDimensionPixelSize(R.styleable.ActionSheet_actionSheetTextSize,
- (int) attrs.actionSheetTextSize);
- a.recycle();
- return attrs;
- }
- @Override
- public void onClick(View v)
- {
- if (v.getId() == BG_VIEW_ID && !mCancelableOnTouchOutside)
- return;
- dismissMenu();
- if (v.getId() != CANCEL_BUTTON_ID && v.getId() != BG_VIEW_ID)
- {
- if (mListener != null)
- mListener.onItemClick(v.getId() - CANCEL_BUTTON_ID - 1);
- isCancel = false;
- }
- }
- /**
- * 自定义属性的控件主题
- *
- * @author Mr.Zheng
- * @date 2014年9月7日 下午10:47:06
- */
- private class Attributes
- {
- private Context mContext;
- private Drawable background;
- private Drawable cancelButtonBackground;
- private Drawable otherButtonTopBackground;
- private Drawable otherButtonMiddleBackground;
- private Drawable otherButtonBottomBackground;
- private Drawable otherButtonSingleBackground;
- private int cancelButtonTextColor;
- private int otherButtonTextColor;
- private int padding;
- private int otherButtonSpacing;
- private int cancelButtonMarginTop;
- private float actionSheetTextSize;
- public Attributes(Context context)
- {
- mContext = context;
- this.background = new ColorDrawable(Color.TRANSPARENT);
- this.cancelButtonBackground = new ColorDrawable(Color.BLACK);
- ColorDrawable gray = new ColorDrawable(Color.GRAY);
- this.otherButtonTopBackground = gray;
- this.otherButtonMiddleBackground = gray;
- this.otherButtonBottomBackground = gray;
- this.otherButtonSingleBackground = gray;
- this.cancelButtonTextColor = Color.WHITE;
- this.otherButtonTextColor = Color.BLACK;
- this.padding = dp2px(20);
- this.otherButtonSpacing = dp2px(2);
- this.cancelButtonMarginTop = dp2px(10);
- this.actionSheetTextSize = dp2px(16);
- }
- private int dp2px(int dp)
- {
- return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, mContext.getResources()
- .getDisplayMetrics());
- }
- public Drawable getOtherButtonMiddleBackground()
- {
- if (otherButtonMiddleBackground instanceof StateListDrawable)
- {
- TypedArray a = mContext.getTheme().obtainStyledAttributes(null, R.styleable.ActionSheet,
- R.attr.actionSheetStyle, 0);
- otherButtonMiddleBackground = a
- .getDrawable(R.styleable.ActionSheet_otherButtonMiddleBackground);
- a.recycle();
- }
- return otherButtonMiddleBackground;
- }
- }
- public static interface MenuItemClickListener
- {
- void onItemClick(int itemPosition);
- }
- }
代码中要注意的地方就是dialog的自定义view要在底部出现,背景要透明,dialog要全屏,这些主要在 ActionSheet 构造方法里设置,即55到61行,然后动态添加控件时注意一下Params就好。其它地方也没什么改动了。
使用
主题我也是直接使用它的,资源配置文件就不贴上来了,其中的属性代表的对应控件去参看ActionSheetForAndroid吧,最后贴上源码地址,改大小、颜色、背景什么的到主题里设置一下换下图片就行了。
我们可以在style直接设置ActionSheet的主题:
- <resources>
- <style name="AppBaseTheme" parent="android:Theme.Light.NoTitleBar"></style>
- <style name="AppTheme" parent="AppBaseTheme">
- <!-- ActionSheet -->
- <item name="actionSheetBackground">@android:color/transparent</item>
- <item name="cancelButtonBackground">@drawable/actionsheet_slt_as_ios7_cancel_bt</item>
- <item name="otherButtonTopBackground">@drawable/actionsheet_slt_as_ios7_other_bt_top</item>
- <item name="otherButtonMiddleBackground">@drawable/actionsheet_slt_as_ios7_other_bt_middle</item>
- <item name="otherButtonBottomBackground">@drawable/actionsheet_slt_as_ios7_other_bt_bottom</item>
- <item name="otherButtonSingleBackground">@drawable/actionsheet_slt_as_ios7_other_bt_single</item>
- <item name="cancelButtonTextColor">#1E82FF</item>
- <item name="otherButtonTextColor">#1E82FF</item>
- <item name="actionSheetPadding">10dp</item>
- <item name="otherButtonSpacing">0dp</item>
- <item name="cancelButtonMarginTop">10dp</item>
- <item name="actionSheetTextSize">16sp</item>
- </style>
- </resources>
也可以在代码里才去设置主题:
- package com.roc.actionsheet;
- import android.os.Bundle;
- import android.support.v4.app.FragmentActivity;
- import android.view.View;
- import android.widget.Toast;
- import com.roc.actionsheet.ActionSheet.MenuItemClickListener;
- /**
- * @author Mr.Zheng
- * @date 2014年9月8日 上午12:08:55
- */
- public class MainActivity extends FragmentActivity implements MenuItemClickListener
- {
- @Override
- protected void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- }
- public void onClick(View v)
- {
- switch (v.getId())
- {
- case R.id.ios6:
- setTheme(R.style.ActionSheetStyleIOS6);
- break;
- case R.id.ios7:
- setTheme(R.style.ActionSheetStyleIOS7);
- break;
- }
- showActionSheet();
- }
- public void showActionSheet()
- {
- ActionSheet menuView = new ActionSheet(this);
- menuView.setCancelButtonTitle("cancel");// before add items
- menuView.addItems("Item1", "Item2", "Item3", "Item4");
- menuView.setItemClickListener(this);
- menuView.setCancelableOnTouchMenuOutside(true);
- menuView.showMenu();
- }
- @Override
- public void onItemClick(int itemPosition)
- {
- Toast.makeText(this, (itemPosition + 1) + " click", 0).show();
- }
- }
是不是挺简单的。下面来看下效果

效果是和用Fragment实现一样的。