标签:
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
return true;
}
//该方法用于创建Menu视图
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_share:
shareCurrentItem();
mode.finish();
return true;
default:
return false;
}
}
//该方法用于对用户的操作做出相应的反馈
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
}
//及时清除mActionMode引用,一者为了垃圾回收,二者为了后面再次进入上下文操作模式考虑
}private ActionMode mActionMode;
someView.setOnLongClickListener(new View.OnLongClickListener() { //someView是一个普通的View控件
public boolean onLongClick(View view) {
if (mActionMode == null) { mActionMode = getActivity().startActionMode(mActionModeCallback)};
//根据情况如果消耗事件则返回true,没有消耗事件则返回false。
view.setSelected(true);
..............
return true;
}
});public ActionMode startActionMode(ActionMode.Callback callback) {
return mWindow.getDecorView().startActionMode(callback);
}public ActionMode startActionMode(ActionMode.Callback callback) {
if (mActionMode != null) { mActionMode.finish(); }
final ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapper(callback);
ActionMode mode = null;
...........
if (mode != null) {
mActionMode = mode;
} else {
if (mActionModeView == null) {//创建ActionModeView
if (isFloating()) {
mActionModeView = new ActionBarContextView(mContext);//note1
mActionModePopup = new PopupWindow(mContext, null,
com.android.internal.R.attr.actionModePopupWindowStyle);
mActionModePopup.setWindowLayoutType(
WindowManager.LayoutParams.TYPE_APPLICATION);
mActionModePopup.setContentView(mActionModeView); //mActionModeView这里是准备被显示的View
mActionModePopup.setWidth(MATCH_PARENT);
TypedValue heightValue = new TypedValue();
mContext.getTheme().resolveAttribute(
com.android.internal.R.attr.actionBarSize, heightValue, true);
final int height = TypedValue.complexToDimensionPixelSize(heightValue.data,
mContext.getResources().getDisplayMetrics());
mActionModeView.setContentHeight(height);
mActionModePopup.setHeight(WRAP_CONTENT);
mShowActionModePopup = new Runnable() {
public void run() {
mActionModePopup.showAtLocation( //note2
mActionModeView.getApplicationWindowToken(),
Gravity.TOP | Gravity.FILL_HORIZONTAL, 0, 0);
}
};
} else {
ViewStub stub = (ViewStub) findViewById(
com.android.internal.R.id.action_mode_bar_stub);
if (stub != null) {
mActionModeView = (ActionBarContextView) stub.inflate();
}
}
}
if (mActionModeView != null) { //显示ActionModeView
mActionModeView.killMode();
mode = new StandaloneActionMode(getContext(), mActionModeView, wrappedCallback,
mActionModePopup == null);
if (callback.onCreateActionMode(mode, mode.getMenu())) {//创建菜单到ActionMode中
mode.invalidate();
mActionModeView.initForMode(mode);//note3
mActionModeView.setVisibility(View.VISIBLE);
mActionMode = mode;
if (mActionModePopup != null) {
post(mShowActionModePopup); //交给Handler去执行前面的Runnable异步方法
}
mActionModeView.sendAccessibilityEvent(
AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
} else {
mActionMode = null;
}
}
}
....
return mActionMode;
}public void showAtLocation(IBinder token, int gravity, int x, int y) {
.........
final WindowManager.LayoutParams p = createPopupLayoutParams(token);
preparePopup(p);
.....
invokePopup(p);
}public void initForMode(final ActionMode mode) {
if (mClose == null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
mClose = inflater.inflate(mCloseItemLayout, this, false);
//看到这里都想哭了,,,,,,,找了半天就是想搞明白那个返回键究竟在哪设置的!!!!
//这里终于找到了,mCloseItemLayout就是定义了返回键的布局文件,它的定义看note1,即ActionBarContextView的构造器。
addView(mClose);
} else if (mClose.getParent() == null) {
addView(mClose);
}
View closeButton = mClose.findViewById(R.id.action_mode_close_button);
closeButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mode.finish(); //点击返回按钮则销毁当前ActionBarContextView视图
}
});
....
}
try {
Field field = popupMenu.getClass().getDeclaredField("mPopup");
field.setAccessible(true);
MenuPopupHelper mHelper = (MenuPopupHelper) field.get(popupMenu);
mHelper.setForceShowIcon(true);
} catch (IllegalAccessException | NoSuchFieldException e) { e.printStackTrace(); } private void showPopupMenu(View v){
PopupMenu popup = new PopupMenu(this, v);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.popmenu, popup.getMenu());
try {
Field field = popup.getClass().getDeclaredField("mPopup");
field.setAccessible(true);
MenuPopupHelper mHelper = (MenuPopupHelper) field.get(popup);
mHelper.setForceShowIcon(true);
} catch (IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace(); }
popup.setOnMenuItemClickListener(new OnPopupMenuItemClickListener(this));
popup.setGravity(Gravity.RIGHT);
popup.show();
} <style name="ProfileTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!--修改PopupMenu的item背景颜色--><!--这里为何一个使用android:而另一个没有android: 是因为前者只有在android 5.0以后版本中才能被使用,后者是兼容模式任何版本都能使用(推荐使用后者)-->
<item name="android:popupMenuStyle">@style/popupMenuProfile</item>
<item name="popupMenuStyle">@style/popupMenuProfile</item>
<!--修改PopupMenu的分界线 注意添加这个会导致menuItem的点击动画发生变化-->
<item name="android:dropDownListViewStyle">@style/dropDownStyle</item>
<item name="dropDownListViewStyle">@style/dropDownStyle</item>
<!--修改PopupMenu的字体颜色-->
<item name="android:textAppearanceLargePopupMenu">@style/popupTextProfile</item>
<item name="textAppearanceLargePopupMenu">@style/popupTextProfile</item>
<!--此处的值也控制ActionBar背景-->
<item name="colorPrimary">@color/black</item>
<!--此处的值也控制ActionBar上面显示电量、信号那行视图的背景-->
<item name="colorPrimaryDark">@color/black</item>
<item name="colorAccent">@color/white</item>
</style>
<style name="popupMenuProfile">
<item name="android:popupBackground">@color/colorAlphaBlack</item>
</style>
<style name="dropDownStyle" parent="android:style/Widget.Holo.ListView.DropDown">
<!--定义这样的style必须定义android:listSelector,否则会使用系统自带的selector那就不知道出什么幺蛾子-->
<item name="android:listSelector">@drawable/profile_popupmenu_selector</item>
<item name="android:divider">#80FFFFFF</item>
<item name="android:dividerHeight">0.5dp</item>
</style>
<style name="popupTextProfile" parent="@style/TextAppearance.Widget.AppCompat.ExpandedMenu.Item">
<item name="android:textColor">@android:color/white</item>
</style><activity
android:name=".activity.others.ProfileActivity"
android:theme="@style/ProfileTheme">
</activity>public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(ITEM_LAYOUT, parent, false); //note1
}
MenuView.ItemView itemView = (MenuView.ItemView) convertView;
if (mForceShowIcon) {
((ListMenuItemView) convertView).setForceShowIcon(true); //note2
}
itemView.initialize(getItem(position), 0); //note3
return convertView;
}final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ListPopupWindow, R.attr.popupMenuStyle, 0);即从主题中定义的popupMenuStyle样式文件中和主题直接定义的属性中获取到如下属性:
<declare-styleable name="ListPopupWindow">
<!-- 下拉垂直偏移距离. -->
<attr name="dropDownVerticalOffset" format="dimension" />
<!-- 下拉水平偏移距离. -->
<attr name="dropDownHorizontalOffset" format="dimension" />
</declare-styleable><declare-styleable name="ListView">
<!-- 为当前ListView指定静态数组资源,而不需要编写Adapter -->
<attr name="entries" />
<!-- listview中item之前的颜色或者Drawable. -->
<attr name="divider" format="reference|color" />
<!-- listview中item之前的相隔距离 . -->
<attr name="dividerHeight" format="dimension" />
<!-- 值为真则lsitview中的Header间不绘制divider,默认值为真 -->
<attr name="headerDividersEnabled" format="boolean" />
<!-- 值为真则lsitview中的Footer间不绘制divider,默认值为真 -->
<attr name="footerDividersEnabled" format="boolean" />
<!-- Drawable to draw above list content. -->
<attr name="overScrollHeader" format="reference|color" />
<!-- Drawable to draw below list content. -->
<attr name="overScrollFooter" format="reference|color" />
</declare-styleable><declare-styleable name="PopupWindow">
<!-- 弹出窗口的背景. -->
<attr name="popupBackground" format="reference|color" />
<!-- 弹出窗口的高度(影响阴影). -->
<attr name="popupElevation" format="dimension" />
<!-- 弹出窗口的动画样式 -->
<attr name="popupAnimationStyle" format="reference" />
<!-- 弹出窗口是否遮盖锚视图 -->
<attr name="overlapAnchor" format="boolean" />
<!-- Transition used to move views into the popup window. -->
<attr name="popupEnterTransition" format="reference" />
<!-- Transition used to move views out of the popup window. -->
<attr name="popupExitTransition" format="reference" />
</declare-styleable>标签:
原文地址:http://blog.csdn.net/evan_man/article/details/51685022