上一节课,我们讲了ActionBar 的左边部分,那么现在我们讲一下ActionBar的右边部分
我们先熟悉一下我们要看的内容,看看再不同的界面下ActionBar是不是有不同的状态?
刚刚进去相册集的时候是不是有拍照按钮?并且右边的菜单是只有一个选择相册?
继续进相册的时候,拍照按钮是不是消失了?右边的菜单变成了多个,包括播放幻灯片?
继续进入单张图片的时候,是不是增加了一个分享的按钮?右边的菜单变的更多了,而且左下角还多了一个编辑按钮?
过了一会,这个ActionBar是不是消失了?
这些都是我们要寻找的问题,带着这些问题我们出发!
首先,我们把目光聚焦在新的文件上 --PhotoPage.java,一个图片的显示界面
public abstract class PhotoPage extends ActivityState implements
PhotoView.Listener, AppBridge.Server, ShareActionProvider.OnShareTargetSelectedListener,
PhotoPageBottomControls.Delegate, GalleryActionBar.OnAlbumModeSelectedListener {
private static final String TAG = "PhotoPage";
private static final int MSG_HIDE_BARS = 1; --要求隐藏状态的消息
刚才我们说了,过了一会儿,这个ActionBar和下面控制条中的按钮就都消失了
处理的函数是
private void hideBars() {
if (!mShowBars) return; --控制标志位
mShowBars = false; --设置标志位
mActionBar.hide(); --隐藏ActionBar
mActivity.getGLRoot().setLightsOutMode(true);
mHandler.removeMessages(MSG_HIDE_BARS); --删除消息
refreshBottomControlsWhenReady(); --刷新下面的控制条
}
重新显示状态条的函数
private void showBars() {
if (mShowBars) return; --控制标志位
mShowBars = true; --设置标志位
mOrientationManager.unlockOrientation();
mActionBar.show(); --显示ActionBar
mActivity.getGLRoot().setLightsOutMode(false);
refreshHidingMessage();
refreshBottomControlsWhenReady(); --刷新下面的控制条
}
我们看到了下面的控制条的代码基本都是在一个类里面实现的
public class PhotoPageBottomControls implements OnClickListener {
public interface Delegate {
public boolean canDisplayBottomControls();
public boolean canDisplayBottomControl(int control);
public void onBottomControlClicked(int control); --回调的接口
public void refreshBottomControlsWhenReady(); --刷新的接口
}
private Delegate mDelegate;
private ViewGroup mParentLayout;
private ViewGroup mContainer;
private boolean mContainerVisible = false;
private Map<View, Boolean> mControlsVisible = new HashMap<View, Boolean>();
private Animation mContainerAnimIn = new AlphaAnimation(0f, 1f);
private Animation mContainerAnimOut = new AlphaAnimation(1f, 0f);
private static final int CONTAINER_ANIM_DURATION_MS = 200;
private static final int CONTROL_ANIM_DURATION_MS = 150;
private static Animation getControlAnimForVisibility(boolean visible) {
Animation anim = visible ? new AlphaAnimation(0f, 1f)
: new AlphaAnimation(1f, 0f);
anim.setDuration(CONTROL_ANIM_DURATION_MS);
return anim;
}
public PhotoPageBottomControls(Delegate delegate, Context context, RelativeLayout layout) {
mDelegate = delegate;
mParentLayout = layout;
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mContainer = (ViewGroup) inflater
.inflate(R.layout.photopage_bottom_controls, mParentLayout, false);--实际的layout
mParentLayout.addView(mContainer);
for (int i = mContainer.getChildCount() - 1; i >= 0; i--) {
View child = mContainer.getChildAt(i);
child.setOnClickListener(this);
mControlsVisible.put(child, false);
}
mContainerAnimIn.setDuration(CONTAINER_ANIM_DURATION_MS);
mContainerAnimOut.setDuration(CONTAINER_ANIM_DURATION_MS);
mDelegate.refreshBottomControlsWhenReady();
}
private void hide() {
mContainer.clearAnimation(); --清理动画
mContainerAnimOut.reset();
mContainer.startAnimation(mContainerAnimOut); --开始新动画飞出
mContainer.setVisibility(View.INVISIBLE); --让整体消失
}
private void show() {
mContainer.clearAnimation(); --清理动画
mContainerAnimIn.reset();
mContainer.startAnimation(mContainerAnimIn); --开始新动画飞入
mContainer.setVisibility(View.VISIBLE);
for (View control : mControlsVisible.keySet()) { --显示所有要显示的控件
if (control.getVisibility() == View.VISIBLE && !control.isEnabled()) {
control.setEnabled(true);
}
}
}
public void refresh() { --控制条的刷新接口
boolean visible = mDelegate.canDisplayBottomControls();
boolean containerVisibilityChanged = (visible != mContainerVisible);
if (containerVisibilityChanged) {
if (visible) {
show();
} else {
hide();
}
mContainerVisible = visible;
}
if (!mContainerVisible) {
return;
}
for (View control : mControlsVisible.keySet()) {
Boolean prevVisibility = mControlsVisible.get(control);
boolean curVisibility = mDelegate.canDisplayBottomControl(control.getId());
if (prevVisibility.booleanValue() != curVisibility) {
if (!containerVisibilityChanged) {
control.clearAnimation();
control.startAnimation(getControlAnimForVisibility(curVisibility));
}
control.setVisibility(curVisibility ? View.VISIBLE : View.INVISIBLE);
mControlsVisible.put(control, curVisibility);
}
}
// Force a layout change
mContainer.requestLayout(); // Kick framework to draw the control.
}
public void cleanup() {
mParentLayout.removeView(mContainer);
mControlsVisible.clear();
}
@Override
public void onClick(View view) { --点击时的调用,并且调用委托的onBottomControlClicked实现回调
Boolean controlVisible = mControlsVisible.get(view);
if (mContainerVisible && controlVisible != null && controlVisible.booleanValue()) {
view.setEnabled(false); --隐藏界面
mDelegate.onBottomControlClicked(view.getId());
}
}
代码好多,一讲就无法收场了,我们再捋一遍,那么我们都知道用户是以下的流程
启动图库-->相册集-->某个相册-->某个图片
gallery-->AlbumSetPage->AlbumPage->PhotoPage
AlbumPage.java 中的
private void pickPhoto(int slotIndex) {
pickPhoto(slotIndex, false);
}
启动某个槽中的图片
Bundle data = new Bundle();
data.putInt(PhotoPage.KEY_INDEX_HINT, slotIndex);
data.putParcelable(PhotoPage.KEY_OPEN_ANIMATION_RECT,
mSlotView.getSlotRect(slotIndex, mRootPane));
data.putString(PhotoPage.KEY_MEDIA_SET_PATH,
mMediaSetPath.toString());
data.putString(PhotoPage.KEY_MEDIA_ITEM_PATH,
item.getPath().toString());
data.putInt(PhotoPage.KEY_ALBUMPAGE_TRANSITION,
PhotoPage.MSG_ALBUMPAGE_STARTED);
data.putBoolean(PhotoPage.KEY_START_IN_FILMSTRIP,
startInFilmstrip);
data.putBoolean(PhotoPage.KEY_IN_CAMERA_ROLL, mMediaSet.isCameraRoll());
if (startInFilmstrip) {
mActivity.getStateManager().switchState(this, FilmstripPage.class, data);
} else {
mActivity.getStateManager().startStateForResult(
SinglePhotoPage.class, REQUEST_PHOTO, data);-- 启动单张图片的界面页
}
SinglePhotoPage中什么也没有写,所有的实现都在父类中
public class SinglePhotoPage extends PhotoPage {
}
单张图片的进入和上下控制条的显示隐藏都已经清楚了,现在我们先把单张图片的ActionBar的标题改掉吧,拍照的图片名称都很长,而且挤在标题栏上,非常拥挤,前面都一样,根本分不清是那张图片。
刷新标题上的内容在PhotoPage.java中的
private void updateTitle(boolean isFilmMode) {
if (isFilmMode) {
mActionBar.setTitle(mMediaSet != null ? mMediaSet.getName() : "");
mActionBar.setDisplayOptions(
((mSecureAlbum == null) && (mSetPathString != null)), false);
} else {
mActionBar.setTitle(mCurrentPhoto != null ? mCurrentPhoto.getName() : "");
mActionBar.setDisplayOptions(
((mSecureAlbum == null) && (mSetPathString != null)), true);
}
}
根据不同的显示模式显示标题,实在OnResume的时候调用刷新的
updateTitle(mPhotoView.getFilmMode());
mActionBar.addOnMenuVisibilityListener(mMenuVisibilityListener);
refreshBottomControlsWhenReady();
mBottomControls.refresh();
底部的刷新也在里面。前面的我们想怎么改就改updateTitel了,比如显示图片的索引和总的张数,后面,我们要把丑陋的分享按钮给弄到下面来,内容太多,休息一下。