From a7b0bf7c10a3a17f4d531a093a953ee2fd93e084 Mon Sep 17 00:00:00 2001 From: Matthew Bishop Date: Thu, 13 Dec 2012 14:47:51 -0700 Subject: [PATCH] Making progress on TwoPaneController -- onMeasure method still needs work --- .gitignore | 1 + bin/R.txt | 11 +- res/layout/vw_actionbar_twopane.xml | 26 +++-- res/values/colors.xml | 42 +++---- .../holo/actionbar/ActionBarButton.java | 10 ++ .../holo/actionbar/ActionBarView.java | 15 ++- .../holo/actionbar/OnePaneController.java | 6 +- .../holo/actionbar/TwoPaneController.java | 104 +++++++++++++----- .../interfaces/ActionBarController.java | 13 ++- .../holo/activities/ActionBarActivity.java | 3 - 10 files changed, 155 insertions(+), 76 deletions(-) diff --git a/.gitignore b/.gitignore index 708a52e..9e6227f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ bin/jarlist.cache +bin/* gen/* \ No newline at end of file diff --git a/bin/R.txt b/bin/R.txt index 43741db..2e97c57 100644 --- a/bin/R.txt +++ b/bin/R.txt @@ -126,6 +126,7 @@ int color background_holo_dark 0x7f070021 int color background_holo_light 0x7f070022 int color black 0x7f07000f int color black_50_opacity 0x7f070010 +int color blue 0x7f07004c int color bright_accent 0x7f070020 int color bright_foreground_disabled_holo_dark 0x7f070025 int color bright_foreground_disabled_holo_light 0x7f070026 @@ -141,6 +142,7 @@ int color dim_foreground_inverse_disabled_holo_dark 0x7f07002c int color dim_foreground_inverse_disabled_holo_light 0x7f070031 int color dim_foreground_inverse_holo_dark 0x7f07002b int color dim_foreground_inverse_holo_light 0x7f070030 +int color green 0x7f07004b int color grey_10 0x7f07000c int color grey_15 0x7f07000b int color grey_20 0x7f07000a @@ -172,11 +174,14 @@ int color holo_orange_light 0x7f070045 int color holo_purple 0x7f070044 int color holo_red_dark 0x7f070043 int color holo_red_light 0x7f070040 +int color indigo 0x7f07004d int color legacy_long_pressed_highlight 0x7f07003d int color legacy_pressed_highlight 0x7f07003b int color legacy_selected_highlight 0x7f07003c int color link_text_holo_dark 0x7f070035 int color link_text_holo_light 0x7f070036 +int color orange 0x7f070049 +int color red 0x7f070048 int color tab_bg_check_off 0x7f070015 int color tab_bg_check_on 0x7f070016 int color tab_top 0x7f070014 @@ -185,10 +190,12 @@ int color textColorHint 0x7f070019 int color textColorLink 0x7f07001a int color textColorPrimary 0x7f070017 int color transparent 0x7f07000d +int color violet 0x7f07004e int color white 0x7f07000e int color white_20_opacity 0x7f070013 int color white_33_opacity 0x7f070012 int color white_50_opacity 0x7f070011 +int color yellow 0x7f07004a int dimen actionbar_height 0x7f080000 int dimen actionbar_underline_height 0x7f080002 int dimen actionbar_underline_offset 0x7f080001 @@ -312,7 +319,7 @@ int id checkable_group 0x7f060063 int id cnt_actionbar_buttons 0x7f06003a int id cnt_actionbar_controller 0x7f060039 int id cnt_btns_left 0x7f060040 -int id cnt_btns_right 0x7f060043 +int id cnt_btns_right 0x7f060042 int id cnt_buttons 0x7f060036 int id cnt_custom_views 0x7f06003b int id cnt_sharelist_item 0x7f06005e @@ -403,7 +410,7 @@ int id two_pane 0x7f060007 int id txt 0x7f06003c int id txt_actionbar_title 0x7f060035 int id txt_title_left 0x7f06003f -int id txt_title_right 0x7f060042 +int id txt_title_right 0x7f060043 int id wed 0x7f060053 int id year 0x7f060049 int layout act_actionbar 0x7f030000 diff --git a/res/layout/vw_actionbar_twopane.xml b/res/layout/vw_actionbar_twopane.xml index 989fd75..8afae10 100644 --- a/res/layout/vw_actionbar_twopane.xml +++ b/res/layout/vw_actionbar_twopane.xml @@ -4,9 +4,10 @@ + android:layout_alignParentLeft="true" + android:background="@color/red" > + android:layout_toRightOf="@+id/cnt_title_left" + android:background="@color/orange" + android:orientation="horizontal" /> + android:layout_toLeftOf="@+id/cnt_btns_right" + android:layout_toRightOf="@+id/cnt_btns_left" + android:background="@color/yellow" > + android:layout_toLeftOf="@+id/icv_overflow" + android:background="@color/green" + android:orientation="horizontal" /> \ No newline at end of file diff --git a/res/values/colors.xml b/res/values/colors.xml index ff03782..fd70565 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -14,39 +14,32 @@ #333333 #262626 #1a1a1a - #00000000 #FFFFFF #000000 - #80000000 #80FFFFFF #54FFFFFF #33FFFFFF - - - @color/bright_accent - @color/background_default - @color/background_highlight - + @color/bright_accent + @color/background_default + @color/background_highlight @color/grey_90 @color/white @color/grey_60 @color/bright_accent - - @color/grey_40 - @color/grey_20 - @color/bright_accent - - @color/grey_20 - @color/grey_30 - + @color/grey_40 + @color/grey_20 + @color/bright_accent + @color/grey_20 + @color/grey_30 @color/holo_blue_light - + #fff3f3f3 #ff000000 + #ff000000 #fff3f3f3 @color/background_holo_light @@ -70,17 +63,17 @@ #5c5cff #0000ee - + #46c5c1ff #2699cc00 - #ffffffff #4699cc00 + #fffeaa0c #fff17a0a #ffffffff @@ -108,5 +101,14 @@ #ffff8800 #ff00ddff - + + + #FF0000 + #FF7F00 + #FFFF00 + #00FF00 + #0000FF + #4B0082 + #8F00FF + \ No newline at end of file diff --git a/src/com/airlocksoftware/holo/actionbar/ActionBarButton.java b/src/com/airlocksoftware/holo/actionbar/ActionBarButton.java index 1a2d65c..0319fc4 100644 --- a/src/com/airlocksoftware/holo/actionbar/ActionBarButton.java +++ b/src/com/airlocksoftware/holo/actionbar/ActionBarButton.java @@ -56,6 +56,16 @@ public ActionBarButton(Context context, AttributeSet attrs) { this.setClickable(true); } + // OVERRIDEN METHODS + @Override + public void onAttachedToWindow() { + super.onAttachedToWindow(); + + // check to make sure drawmode is set + if (mDrawMode == null) throw new RuntimeException("You forgot to set the DrawMode for the ActionBarButton" + + toString()); + } + // PUBLIC API /** Set the mode of this button. **/ public ActionBarButton priority(Priority priority) { diff --git a/src/com/airlocksoftware/holo/actionbar/ActionBarView.java b/src/com/airlocksoftware/holo/actionbar/ActionBarView.java index 70a26a2..7c66fac 100644 --- a/src/com/airlocksoftware/holo/actionbar/ActionBarView.java +++ b/src/com/airlocksoftware/holo/actionbar/ActionBarView.java @@ -35,7 +35,7 @@ public class ActionBarView extends RelativeLayout { OverlayManager mOverlayManager; private boolean mLayoutFinished = false; - // private boolean mNeedsLayout = false; + private boolean mNeedsLayout = false; // CONSTANTS private static final String TAG = ActionBarView.class.getSimpleName(); @@ -65,8 +65,8 @@ public ActionBarView(Context context, AttributeSet attrs) { mUpIndicator = (IconView) findViewById(R.id.icv_up_indicator); mUpIcon = findViewById(R.id.img_up_icon); - // TODO get the proper background resource + // get the background drawable & make sure it repeats properly TypedValue typedValue = new TypedValue(); mContext.getTheme() .resolveAttribute(R.attr.actionBarBg, typedValue, true); @@ -140,11 +140,16 @@ public View findView(int id) { * If any buttons won't fit, move them to the OverflowMenu. **/ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); - if (mLayoutFinished) { - // TODO get width and height of mControllerContainer instead - mController.onMeasure(widthMeasureSpec, heightMeasureSpec); + if (mLayoutFinished && mNeedsLayout) { + mController.onMeasure(mControllerContainer.getMeasuredWidth(), mControllerContainer.getMeasuredHeight()); + mNeedsLayout = false; } } + + public void requestNeedsLayout() { + mNeedsLayout = true; + requestLayout(); + } public ViewGroup getControllerContainer() { return mControllerContainer; diff --git a/src/com/airlocksoftware/holo/actionbar/OnePaneController.java b/src/com/airlocksoftware/holo/actionbar/OnePaneController.java index 49bd909..22166d1 100644 --- a/src/com/airlocksoftware/holo/actionbar/OnePaneController.java +++ b/src/com/airlocksoftware/holo/actionbar/OnePaneController.java @@ -43,7 +43,6 @@ public class OnePaneController implements ActionBarController { private List mLowButtons = new ArrayList(); // STATE - private boolean mNeedsLayout = false; // CONSTANTS private static final int ONE_PANE_LAYOUT_RES = R.layout.vw_actionbar_onepane; @@ -71,8 +70,7 @@ public OnePaneController(Context context, ActionBarView actionBar) { public void addButton(ActionBarButton button) { if (button.priority() == Priority.HIGH) mHighButtons.add(button); else mLowButtons.add(button); - mNeedsLayout = true; - mControllerContainer.requestLayout(); + mActionBar.requestNeedsLayout(); } @Override @@ -99,7 +97,7 @@ public void addOverflowView(View toAdd) { @Override public void removeOverflowView(View toRemove) { mOverflow.removeView(toRemove); - mControllerContainer.requestLayout(); + mActionBar.requestNeedsLayout(); } @Override diff --git a/src/com/airlocksoftware/holo/actionbar/TwoPaneController.java b/src/com/airlocksoftware/holo/actionbar/TwoPaneController.java index 00f4d07..e420f26 100644 --- a/src/com/airlocksoftware/holo/actionbar/TwoPaneController.java +++ b/src/com/airlocksoftware/holo/actionbar/TwoPaneController.java @@ -1,7 +1,9 @@ package com.airlocksoftware.holo.actionbar; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import android.content.Context; import android.view.LayoutInflater; @@ -10,8 +12,8 @@ import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.RelativeLayout; -import android.widget.TextView; import android.widget.RelativeLayout.LayoutParams; +import android.widget.TextView; import com.airlocksoftware.holo.R; import com.airlocksoftware.holo.actionbar.ActionBarButton.DrawMode; @@ -19,6 +21,7 @@ import com.airlocksoftware.holo.actionbar.interfaces.ActionBarController; import com.airlocksoftware.holo.image.IconView; import com.airlocksoftware.holo.type.FontText; +import com.airlocksoftware.holo.utils.Utils; import com.airlocksoftware.holo.utils.ViewUtils; public class TwoPaneController implements ActionBarController { @@ -30,21 +33,15 @@ public class TwoPaneController implements ActionBarController { private ActionBarOverflow mOverflow; // STATE - /** Controls which half of the ActionBar Buttons / Titles get added to. **/ - private boolean mAddToLeftSide = false; + /** Controls which half of the ActionBar Buttons / Titles get added to. Default is right side. **/ + public Side mActiveSide = Side.RIGHT; private int mLeftPaneWidth; // VIEWS - ViewGroup mTitleLeft; - TextView mTitleTextLeft; - ViewGroup mButtonsLeft; - ViewGroup mTitleRight; - TextView mTitleTextRight; - ViewGroup mButtonsRight; + ViewGroup mTitleLeft, mTitleRight, mButtonsLeft, mButtonsRight; + TextView mTitleTextLeft, mTitleTextRight; IconView mOverflowIcon; - // TODO keep a separate reference for whichever is active (or just switch them all out when - private List mLowRightButtons = new ArrayList(); private List mHighRightButtons = new ArrayList(); private List mLowLeftButtons = new ArrayList(); @@ -52,6 +49,7 @@ public class TwoPaneController implements ActionBarController { // CONSTANTS private static final int TWO_PANE_LAYOUT_RES = R.layout.vw_actionbar_twopane; + private static final int LEFT_PANE_DEFAULT_SIZE = 320;// in dp public static final int TWOPANE_LEFT_TAG = 0; public static final int TWOPANE_RIGHT_TAG = 1; @@ -69,6 +67,7 @@ public TwoPaneController(Context context, ActionBarView actionBar) { ACTIONBAR_HEIGHT = mContext.getResources() .getDimensionPixelSize(R.dimen.actionbar_height); + this.setLeftPaneWidth(Utils.dpToPixels(context, LEFT_PANE_DEFAULT_SIZE)); // matches value in vw_actionbar_twopane inflateLayout(LayoutInflater.from(mContext)); } @@ -77,13 +76,13 @@ public TwoPaneController(Context context, ActionBarView actionBar) { @Override public void addButton(ActionBarButton button) { if (button.priority() == Priority.HIGH) { - if (mAddToLeftSide) mHighLeftButtons.add(button); + if (mActiveSide == Side.LEFT) mHighLeftButtons.add(button); else mHighRightButtons.add(button); } else { - if (mAddToLeftSide) mLowLeftButtons.add(button); + if (mActiveSide == Side.LEFT) mLowLeftButtons.add(button); else mLowRightButtons.add(button); } - mActionBar.requestLayout(); + mActionBar.requestNeedsLayout(); } @Override @@ -116,7 +115,7 @@ public void addOverflowView(View toAdd) { @Override public void setTitleText(String text) { - if (mAddToLeftSide) { + if (mActiveSide == Side.LEFT) { if (text == null) mTitleTextLeft.setVisibility(View.GONE); else { mTitleTextLeft.setVisibility(View.VISIBLE); @@ -137,13 +136,13 @@ public void setTitleText(String text) { @Override public void removeOverflowView(View toRemove) { mOverflow.removeView(toRemove); - mActionBar.requestLayout(); + mActionBar.requestNeedsLayout(); } @Override public ViewGroup getTitleGroup() { ViewGroup container = null; - if (mAddToLeftSide) { + if (mActiveSide == Side.LEFT) { mTitleTextLeft.setVisibility(View.GONE); container = mTitleLeft; } else { @@ -155,7 +154,7 @@ public ViewGroup getTitleGroup() { @Override public void clearTitleGroup() { - if (mAddToLeftSide) { + if (mActiveSide == Side.LEFT) { for (View v : ViewUtils.directChildViews(mTitleLeft)) { if (v != mTitleTextLeft) mTitleLeft.removeView(v); } @@ -166,8 +165,29 @@ public void clearTitleGroup() { } } + @SuppressWarnings("unused") @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + + mButtonsLeft.removeAllViews(); + mButtonsRight.removeAllViews(); + + // TODO temporary + for (ActionBarButton btn : mHighLeftButtons) { + mButtonsLeft.addView(btn.drawMode(DrawMode.ICON_ONLY)); + } + for (ActionBarButton btn : mLowLeftButtons) { + mButtonsLeft.addView(btn.drawMode(DrawMode.ICON_ONLY)); + } + for (ActionBarButton btn : mHighRightButtons) { + mButtonsRight.addView(btn.drawMode(DrawMode.ICON_ONLY)); + } + for (ActionBarButton btn : mLowRightButtons) { + mButtonsRight.addView(btn.drawMode(DrawMode.ICON_ONLY)); + } + + if (1 < 2) return; + mButtonsLeft.removeAllViews(); mButtonsRight.removeAllViews(); mOverflow.removeActionBarButtons(); @@ -203,7 +223,7 @@ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { availableLeftWidth -= titleLeftWidth; } mTitleLeft.setLayoutParams(params); - + // low buttons for (ActionBarButton btn : mLowLeftButtons) { if (availableLeftWidth > ACTIONBAR_HEIGHT) { @@ -214,7 +234,7 @@ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { leftHasOverflowed = true; } } - + // setup right side // // should add all views in one go, because the next onMeasure isn't called synchronously @@ -271,8 +291,8 @@ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // PUBLIC METHODS /** Controls which half of the ActionBar we are adding Buttons & titles to. **/ - public void setAddToLeftSide(boolean addToLeft) { - mAddToLeftSide = addToLeft; + public void setActiveSide(Side currentSide) { + mActiveSide = currentSide; } public void setLeftPaneWidth(int px) { @@ -284,12 +304,12 @@ public void setLeftPaneWidth(int px) { private void inflateLayout(LayoutInflater inflater) { inflater.inflate(TWO_PANE_LAYOUT_RES, mControllerContainer); - mTitleLeft = (RelativeLayout) mControllerContainer.findViewById(R.id.cnt_title_left); + mTitleLeft = (ViewGroup) mControllerContainer.findViewById(R.id.cnt_title_left); mTitleTextLeft = (FontText) mControllerContainer.findViewById(R.id.txt_title_left); - mTitleRight = (RelativeLayout) mControllerContainer.findViewById(R.id.cnt_title_right); - mTitleTextRight = (FontText) mControllerContainer.findViewById(R.id.txt_title_left); - mButtonsLeft = (LinearLayout) mControllerContainer.findViewById(R.id.cnt_btns_left); - mButtonsRight = (LinearLayout) mControllerContainer.findViewById(R.id.cnt_btns_right); + mTitleRight = (ViewGroup) mControllerContainer.findViewById(R.id.cnt_title_right); + mTitleTextRight = (FontText) mControllerContainer.findViewById(R.id.txt_title_right); + mButtonsLeft = (ViewGroup) mControllerContainer.findViewById(R.id.cnt_btns_left); + mButtonsRight = (ViewGroup) mControllerContainer.findViewById(R.id.cnt_btns_right); mOverflowIcon = (IconView) mControllerContainer.findViewById(R.id.icv_overflow); @@ -301,4 +321,34 @@ public void onClick(View v) { }); } + // ENUMS + public enum Side { + LEFT, RIGHT; + } + + /** Used to implement a HashMap that maps from a Side and Priority to a list of buttons. **/ + public class BtnKey { + private Side mSide; + private Priority mPriority; + + public BtnKey(Side side, Priority priority) { + mSide = side; + mPriority = priority; + } + + @Override + public int hashCode() { + int code = 1; + if (mSide != null) code += 2 * mSide.ordinal(); + if (mPriority != null) code += 3 * mPriority.ordinal(); + return code; + } + + @Override + public boolean equals(Object o) { + if (o == null || !(o instanceof BtnKey)) return false; + BtnKey toCheck = (BtnKey) o; + return toCheck.mPriority == this.mPriority && toCheck.mSide == this.mSide; + } + } } diff --git a/src/com/airlocksoftware/holo/actionbar/interfaces/ActionBarController.java b/src/com/airlocksoftware/holo/actionbar/interfaces/ActionBarController.java index 01be9c6..99af253 100644 --- a/src/com/airlocksoftware/holo/actionbar/interfaces/ActionBarController.java +++ b/src/com/airlocksoftware/holo/actionbar/interfaces/ActionBarController.java @@ -12,9 +12,9 @@ * through the ActionBarClient interface. **/ public interface ActionBarController { - -// /** Common method for initializing the controller once the ActionBar has been created. **/ -// public void initialize(Context context, ActionBarView actionBar); + + // /** Common method for initializing the controller once the ActionBar has been created. **/ + // public void initialize(Context context, ActionBarView actionBar); /** Add an ActionBarButton to either the overflow or the HIGH_PRIORITY button area. **/ public void addButton(ActionBarButton button); @@ -33,11 +33,14 @@ public interface ActionBarController { /** Get the ViewGroup that can be used for custom titles. Empty when cleaning up ActionBar. **/ public ViewGroup getTitleGroup(); - + /** Returns the title group to the default state (i.e. an empty textview being the only child) **/ public void clearTitleGroup(); - /** Called by ActionBarView when it's own onMeasure method is called. **/ + /** + * Called by ActionBarView when it's own onMeasure method is called. Don't forget to set the draw mode of the + * ActionBarButtons! + **/ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec); } diff --git a/src/com/airlocksoftware/holo/activities/ActionBarActivity.java b/src/com/airlocksoftware/holo/activities/ActionBarActivity.java index 116d111..4b6a45f 100644 --- a/src/com/airlocksoftware/holo/activities/ActionBarActivity.java +++ b/src/com/airlocksoftware/holo/activities/ActionBarActivity.java @@ -124,7 +124,4 @@ public void addOnStopListener(OnStopListener listener) { mOnStopListeners.add(listener); } -// public void setActionBarController(ActionBarController controller) { -// mController = controller; -// } }