From c014cccc2c4ed0b44ba57c0f080dcbf8d0becb8f Mon Sep 17 00:00:00 2001 From: Sam Bosley Date: Fri, 13 Jan 2012 15:48:16 -0800 Subject: [PATCH] Popover list selection menu --- astrid/res/drawable/list_arrow_down.png | Bin 0 -> 1736 bytes astrid/res/drawable/list_arrow_up.png | Bin 0 -> 1735 bytes astrid/res/drawable/list_popover_bg.9.png | Bin 0 -> 147 bytes astrid/res/layout/header_nav_views.xml | 15 ++++ astrid/res/layout/list_dropdown_popover.xml | 33 +++++++++ .../activity/AstridWrapperActivity.java | 20 ++++-- .../activity/TaskListWrapperActivity.java | 66 ++++++++++++------ .../todoroo/astrid/adapter/FilterAdapter.java | 7 +- .../astrid/ui/ListDropdownPopover.java | 61 ++++++++++++++++ 9 files changed, 172 insertions(+), 30 deletions(-) create mode 100644 astrid/res/drawable/list_arrow_down.png create mode 100644 astrid/res/drawable/list_arrow_up.png create mode 100644 astrid/res/drawable/list_popover_bg.9.png create mode 100644 astrid/res/layout/header_nav_views.xml create mode 100644 astrid/res/layout/list_dropdown_popover.xml create mode 100644 astrid/src/com/todoroo/astrid/ui/ListDropdownPopover.java diff --git a/astrid/res/drawable/list_arrow_down.png b/astrid/res/drawable/list_arrow_down.png new file mode 100644 index 0000000000000000000000000000000000000000..b34eb1246d72d21a26dd0275933e22f5860d5411 GIT binary patch literal 1736 zcmeAS@N?(olHy`uVBq!ia0vp^8bB<Wn zs9z&x-*5iRCwDBT>i?CDjW zmS$q=FpKjL`%xz=?;Q>nGcq51=Dl&QQRIob+R90K-8QRTgY=)KxNhS4_Cdb5`BVIc z6;oc$Ui)02H+Pn#-^H4)d-9gG1wGFgt{$|Hm)PsLV{So&+2h5gbxvnh)(NWZeg3W_ zbH>}$S<@pmg;Zr!_9TU@GtS9;#?9P0>)GYEUjim=m~XP*#5nTvLNaZn@^QdWU~|zke<2dRjT@!|N?_y;r|PPqGTTef!DTWy*(-ln2@~ zdpI@q$)spJnCQflI4k+csvkaLl1g4nE@hU4RBp1kX00)K+FKd-ij(ntJL1H?MsM2j z?ZNMPcU7TKmrub(}N(Z9|fdbp zRtZaP+PH6HT^NVoo;9U>ZI@q{@PsmGkM~s z^LVcJxT&|ny8kWnw%}{A&obkSEkA1&yp;ZX__dySC|jK5fs4g@;tPyRpKxxdiPL#4 zdRyLR-u8xx*0+<_+U6$i>b478eY-?2T8?oy|LUvr&#$_A_xY20?ux~K*j6fYT|2Ze z-UygsI14-?iy0WWg+Z8+Vb&Z81_s8w%#etZ2wxwolpi<;HsXMd|v6mX?MdTGO$heuS->=*#-a1c z)IVJ=hb2YTEmchfLIfuDuc$0g+@HkBeyFr>@&X~nmA$jx1^*QF%u$F*Khkz&W`d9U z$5ewiQTl?yJ58koeX^tGE@Rm`@#VGIku1ueUN8D+e$6w3*YVR_*WjXwm)l}knq88= z$fP;&ON8jS+I23som+mbCDf{X&L(>?KW!23NzRV4dsx>Ul=PUqX4a~WGpEntJ8}1* zhV;4`u6hn0m&d+u!mqjd-T!wdsAIt@=OUq{^+vy*noqowuNSHQ+G^5H!})%11S}Y~ zPh^c<_~iHRmzC##Jlt*?@%P~TL$X`aFPtoV!+9Y$SunP1&MT333sfD|zi-^WcK(G{ z>-5)C-X%nwm=X9U^FnC9uA|*&_Z#odURr9M(e3<9pj!OJ-`qcJmRJ8VeG=Z~_;iBQ QJWvkuboFyt=akR{0E?XL(EtDd literal 0 HcmV?d00001 diff --git a/astrid/res/drawable/list_arrow_up.png b/astrid/res/drawable/list_arrow_up.png new file mode 100644 index 0000000000000000000000000000000000000000..23e53ba9423c4fcdaeab7dd0ca9e03eadc1c9e54 GIT binary patch literal 1735 zcmeAS@N?(olHy`uVBq!ia0vp^8bB<Wn zs9z&x-*5iRCwDBT>i?CDjW zmS$q=FpKjL`%xz=?;Q>nGcq51=Dl&QQRIob+R90K-8QRTgY=)KxNhS4_Cdb5`BVIc z6;oc$Ui)02H+Pn#-^H4)d-9gG1wGFgt{$|Hm)PsLV{So&+2h5gbxvnh)(NWZeg3W_ zbH>}$S<@pmg;Zr!_9TU@GtS9;#?9P0>)GYEUjim=m~XP*#5nTvLNaZn@^QdWU~|zke<2dRjT@!|N?_y;r|PPqGTTef!DTWy*(-ln2@~ zdpI@q$)spJnCQflI4k+csvkaLl1g4nE@hU4RBp1kX00)K+FKd-ij(ntJL1H?MsM2j z?ZNMPcU7TKmrub(}N(Z9|fdbp zRtZaP+PH6HT^NVoo;9U>ZI@q{@PsmGkM~s z^LVcJxT&|ny8kWnw%}{A&obkSEkA1&yp;ZX__dySC|jK5fs4g@;tPyRpKxxdiPL#4 zdRyLR-u8xx*0+<_+U6$i>b478eY-?2T8?oy|LUvr&#$_A_xY20?ux~K*j6fYT|2Ze z-UygsI14-?iy0WWg+Z8+Vb&Z81_s8w%#etZ2wxwolpi<;HsXMd|v6mX?zC!6qRfuV=$b2vPgm}fg(3d;6#kjAr+U|YyUBfE> zBX^4KOlRC!syLI=DUWZ8?~;)AXJ#RVcbz{SlAZMKq>Dh&=L0#)b6*z3WwYjsTDGr{ zW6y80XigU>+I+W2=|ofo(t>ZVz~zre5XGwr7Es_6<(z61*uMGGHjJjGo2dqPd& zQESd^8;Z@QyYr-a*xly47~CE@aq`UU(C0pS!Wze~yfNg&{ypu{!49z zmAd_({f5Q6wq;MZmsBs1n$A#Z^HurJ^tr-%&#GK2-M_Uw*!uEk{{8r1-&4!O*!DSr OGLWaMpUXO@geCyH6YY2a literal 0 HcmV?d00001 diff --git a/astrid/res/drawable/list_popover_bg.9.png b/astrid/res/drawable/list_popover_bg.9.png new file mode 100644 index 0000000000000000000000000000000000000000..11f3cf18c3cfa57a8ae4ec36014e8444bc60df5b GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^S|H591|*LjJ{b+9qC8z3Ln>~)y?K!HfP#Qap!62| z*BcxkJE|OHbNj^h@9#mm?Ni>nMI3*%=4@3&?#*vP6Z7BLmGkE}G+_h(1gg$%ez@wp d?;qzkjLe}=Pl~_wdjqtE!PC{xWt~$(696fTJcIxM literal 0 HcmV?d00001 diff --git a/astrid/res/layout/header_nav_views.xml b/astrid/res/layout/header_nav_views.xml new file mode 100644 index 000000000..42689ecd9 --- /dev/null +++ b/astrid/res/layout/header_nav_views.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/astrid/res/layout/list_dropdown_popover.xml b/astrid/res/layout/list_dropdown_popover.xml new file mode 100644 index 000000000..46be7a04b --- /dev/null +++ b/astrid/res/layout/list_dropdown_popover.xml @@ -0,0 +1,33 @@ + + + + + + + + + + diff --git a/astrid/src/com/todoroo/astrid/activity/AstridWrapperActivity.java b/astrid/src/com/todoroo/astrid/activity/AstridWrapperActivity.java index 1d1319d7d..9cc79f48e 100644 --- a/astrid/src/com/todoroo/astrid/activity/AstridWrapperActivity.java +++ b/astrid/src/com/todoroo/astrid/activity/AstridWrapperActivity.java @@ -6,6 +6,7 @@ import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; +import android.view.ViewGroup; import com.timsu.astrid.R; import com.todoroo.andlib.utility.AndroidUtilities; @@ -85,8 +86,8 @@ public class AstridWrapperActivity extends FragmentActivity * Handles items being clicked from the filterlist-fragment. Return true if item is handled. */ public boolean onFilterItemClicked(FilterListItem item) { - if (this instanceof TaskListWrapperActivity) { - ((TaskListWrapperActivity) this).setSelectedItem(item); + if (this instanceof TaskListWrapperActivity && (item instanceof Filter) ) { + ((TaskListWrapperActivity) this).setSelectedItem((Filter) item); } if (!mMultipleFragments || (item instanceof SearchFilter)) { if(item instanceof Filter) { @@ -168,13 +169,20 @@ public class AstridWrapperActivity extends FragmentActivity protected void setupFilterlistFragment() { FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); - FilterListActivity newFragment = new FilterListActivity(); - if (findViewById(R.id.filterlist_fragment_container) != null) { - transaction.replace(R.id.filterlist_fragment_container, newFragment, FilterListActivity.TAG_FILTERLIST_FRAGMENT); + FilterListActivity frag = getFilterListFragment(); + if (frag == null) + frag = new FilterListActivity(); + + ViewGroup container = (ViewGroup) findViewById(R.id.filterlist_fragment_container); + if (container != null) { + if (container.getChildCount() > 0) + transaction.replace(R.id.filterlist_fragment_container, frag, FilterListActivity.TAG_FILTERLIST_FRAGMENT); + else + transaction.add(R.id.filterlist_fragment_container, frag, FilterListActivity.TAG_FILTERLIST_FRAGMENT); } else { if (getFilterListFragment() != null) return; - transaction.add(newFragment, FilterListActivity.TAG_FILTERLIST_FRAGMENT); + transaction.add(frag, FilterListActivity.TAG_FILTERLIST_FRAGMENT); } transaction.commit(); } diff --git a/astrid/src/com/todoroo/astrid/activity/TaskListWrapperActivity.java b/astrid/src/com/todoroo/astrid/activity/TaskListWrapperActivity.java index 799b6e56e..a1fe34a3c 100644 --- a/astrid/src/com/todoroo/astrid/activity/TaskListWrapperActivity.java +++ b/astrid/src/com/todoroo/astrid/activity/TaskListWrapperActivity.java @@ -3,20 +3,38 @@ package com.todoroo.astrid.activity; import android.os.Bundle; import android.support.v4.app.ActionBar; import android.support.v4.app.Fragment; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; +import android.widget.TextView; import com.timsu.astrid.R; import com.todoroo.andlib.utility.AndroidUtilities; import com.todoroo.astrid.api.Filter; -import com.todoroo.astrid.api.FilterListItem; import com.todoroo.astrid.service.ThemeService; +import com.todoroo.astrid.ui.ListDropdownPopover; public class TaskListWrapperActivity extends AstridWrapperActivity { public static final String TOKEN_SELECTED_FILTER = "selectedFilter"; - private int selectionToSet; - - private ArrayAdapter listDropdownAdapter; + private int currSelection; + private TextView lists; + + private ArrayAdapter listDropdownAdapter; + private ListDropdownPopover popover; + + private final OnItemClickListener listClickListener = new OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Filter item = listDropdownAdapter.getItem(position); + currSelection = position; + onFilterItemClicked(item); + popover.dismiss(); + lists.setText(item.title); + } + }; /** * @see android.app.Activity#onCreate(Bundle) */ @@ -33,11 +51,24 @@ public class TaskListWrapperActivity extends AstridWrapperActivity { setupFilterlistFragment(); ActionBar actionBar = getSupportActionBar(); - actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); actionBar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE); + actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); + actionBar.setCustomView(R.layout.header_nav_views); + + popover = new ListDropdownPopover(TaskListWrapperActivity.this, R.layout.list_dropdown_popover); + + lists = (TextView) actionBar.getCustomView().findViewById(R.id.lists_nav); + lists.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + popover.show(v); + } + }); + currSelection = 0; + if (savedInstanceState != null) { - selectionToSet = savedInstanceState.getInt(TOKEN_SELECTED_FILTER); + currSelection = savedInstanceState.getInt(TOKEN_SELECTED_FILTER); } } @@ -59,30 +90,23 @@ public class TaskListWrapperActivity extends AstridWrapperActivity { } } - public void updateDropdownNav(ArrayAdapter arrayAdapter) { + public void updateDropdownNav(ArrayAdapter arrayAdapter) { listDropdownAdapter = arrayAdapter; - ActionBar actionBar = getSupportActionBar(); - actionBar.setListNavigationCallbacks(arrayAdapter, new ActionBar.OnNavigationListener() { - @Override - public boolean onNavigationItemSelected(int itemPosition, long itemId) { - onFilterItemClicked(listDropdownAdapter.getItem(itemPosition)); - return true; - } - }); - if (selectionToSet < listDropdownAdapter.getCount()) { - getSupportActionBar().setSelectedNavigationItem(selectionToSet); + popover.setAdapter(listDropdownAdapter, listClickListener); + if (currSelection < listDropdownAdapter.getCount()) { + lists.setText(listDropdownAdapter.getItem(currSelection).title); } } @Override protected void onSaveInstanceState(Bundle icicle) { - icicle.putInt(TOKEN_SELECTED_FILTER, getSupportActionBar().getSelectedNavigationIndex()); + icicle.putInt(TOKEN_SELECTED_FILTER, currSelection); super.onSaveInstanceState(icicle); } - public void setSelectedItem(FilterListItem item) { - int position = listDropdownAdapter.getPosition(item); - getSupportActionBar().setSelectedNavigationItem(position); + public void setSelectedItem(Filter item) { + currSelection = listDropdownAdapter.getPosition(item); + lists.setText(item.title); } @Override diff --git a/astrid/src/com/todoroo/astrid/adapter/FilterAdapter.java b/astrid/src/com/todoroo/astrid/adapter/FilterAdapter.java index e4402dc81..85480a2cf 100644 --- a/astrid/src/com/todoroo/astrid/adapter/FilterAdapter.java +++ b/astrid/src/com/todoroo/astrid/adapter/FilterAdapter.java @@ -365,8 +365,8 @@ public class FilterAdapter extends BaseExpandableListAdapter { for (Filter f : children) { arrayAdapter.add(f); } - } else { - arrayAdapter.add(filter); + } else if (filter instanceof Filter){ + arrayAdapter.add((Filter) filter); } } notifyDataSetChanged(); @@ -628,7 +628,7 @@ public class FilterAdapter extends BaseExpandableListAdapter { }); } - private class FilterArrayAdapter extends ArrayAdapter { + private class FilterArrayAdapter extends ArrayAdapter { public FilterArrayAdapter(Context context) { super(context, 0); @@ -640,6 +640,7 @@ public class FilterAdapter extends BaseExpandableListAdapter { ViewHolder viewHolder = (ViewHolder) convertView.getTag(); viewHolder.item = (FilterListItem) getItem(position); populateView(viewHolder, false); + viewHolder.name.setTextColor(Color.WHITE); return convertView; } diff --git a/astrid/src/com/todoroo/astrid/ui/ListDropdownPopover.java b/astrid/src/com/todoroo/astrid/ui/ListDropdownPopover.java new file mode 100644 index 000000000..2ba4b5841 --- /dev/null +++ b/astrid/src/com/todoroo/astrid/ui/ListDropdownPopover.java @@ -0,0 +1,61 @@ +package com.todoroo.astrid.ui; + +import greendroid.widget.QuickAction; +import greendroid.widget.QuickActionWidget; + +import java.util.List; + +import android.R; +import android.content.Context; +import android.graphics.Rect; +import android.view.View; +import android.view.View.MeasureSpec; +import android.view.ViewGroup; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.FrameLayout; +import android.widget.ListAdapter; +import android.widget.ListView; + + +public class ListDropdownPopover extends QuickActionWidget { + + private final ListView listView; + + public ListDropdownPopover(Context context, int layout) { + super(context); + setContentView(layout); + + listView = (ListView) getContentView().findViewById(R.id.list); + + setFocusable(true); + setTouchable(true); + } + + public void setAdapter(ListAdapter adapter, OnItemClickListener listener) { + listView.setAdapter(adapter); + listView.setOnItemClickListener(listener); + } + + @Override + protected void populateQuickActions(List quickActions) { + // Do nothing + } + + @Override + protected void onMeasureAndLayout(Rect anchorRect, View contentView) { + contentView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + contentView.measure(MeasureSpec.makeMeasureSpec(getScreenWidth(), MeasureSpec.EXACTLY), + ViewGroup.LayoutParams.WRAP_CONTENT); + + int rootHeight = contentView.getMeasuredHeight(); + + int offsetY = getArrowOffsetY(); + int dyTop = anchorRect.top; + int dyBottom = getScreenHeight() - anchorRect.bottom; + + boolean onTop = (dyTop > dyBottom); + int popupY = (onTop) ? anchorRect.top - rootHeight + offsetY : anchorRect.bottom - offsetY; + + setWidgetSpecs(popupY, onTop); + } +}