author | Sebastian Kaspari <s.kaspari@gmail.com> |
Thu, 04 Jun 2015 18:13:07 -0700 | |
changeset 248152 | 70924ca5242302f1e0d1a2e5f3dfcd33770154d2 |
parent 248151 | 646bc6779d35f9f9db3088fb6fdfe53d7355a6d4 |
child 248153 | c3e6440a410d4b9485c6e58f76fdbb78d9c1ef2e |
push id | 60888 |
push user | kwierso@gmail.com |
push date | Thu, 11 Jun 2015 01:38:38 +0000 |
treeherder | mozilla-inbound@39e638ed06bf [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mcomella |
bugs | 1158295 |
milestone | 41.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/mobile/android/base/home/SearchEngineBar.java +++ b/mobile/android/base/home/SearchEngineBar.java @@ -4,45 +4,63 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.gecko.home; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; -import android.widget.FrameLayout; import android.widget.ImageView; import org.mozilla.gecko.R; -import org.mozilla.gecko.widget.FaviconView; import org.mozilla.gecko.widget.TwoWayView; import java.util.ArrayList; import java.util.List; public class SearchEngineBar extends TwoWayView implements AdapterView.OnItemClickListener { private static final String LOGTAG = "Gecko" + SearchEngineBar.class.getSimpleName(); + private static final float ICON_CONTAINER_MIN_WIDTH_DP = 72; + private static final float DIVIDER_HEIGHT_DP = 1; + public interface OnSearchBarClickListener { public void onSearchBarClickListener(SearchEngine searchEngine); } private final SearchEngineAdapter adapter; + private final Paint dividerPaint; + private final float minIconContainerWidth; + private final float dividerHeight; + + private int iconContainerWidth; private OnSearchBarClickListener onSearchBarClickListener; public SearchEngineBar(final Context context, final AttributeSet attrs) { super(context, attrs); + dividerPaint = new Paint(); + dividerPaint.setColor(getResources().getColor(R.color.divider_light)); + dividerPaint.setStyle(Paint.Style.FILL_AND_STROKE); + + final DisplayMetrics displayMetrics = getResources().getDisplayMetrics(); + minIconContainerWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, ICON_CONTAINER_MIN_WIDTH_DP, displayMetrics); + dividerHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DIVIDER_HEIGHT_DP, displayMetrics); + + iconContainerWidth = (int) minIconContainerWidth; + adapter = new SearchEngineAdapter(); setAdapter(adapter); setOnItemClickListener(this); } @Override public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) { @@ -58,16 +76,44 @@ public class SearchEngineBar extends Two protected void setOnSearchBarClickListener(final OnSearchBarClickListener listener) { onSearchBarClickListener = listener; } protected void setSearchEngines(final List<SearchEngine> searchEngines) { adapter.setSearchEngines(searchEngines); } + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + final int searchEngineCount = getCount(); + + if (searchEngineCount > 0) { + final float availableWidthPerContainer = getMeasuredWidth() / searchEngineCount; + + final int desiredIconContainerSize = (int) Math.max( + availableWidthPerContainer, + minIconContainerWidth + ); + + if (desiredIconContainerSize != iconContainerWidth) { + iconContainerWidth = desiredIconContainerSize; + adapter.notifyDataSetChanged(); + } + } + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + canvas.drawRect(0, 0, getWidth(), dividerHeight, dividerPaint); + } + public class SearchEngineAdapter extends BaseAdapter { List<SearchEngine> searchEngines = new ArrayList<>(); public void setSearchEngines(final List<SearchEngine> searchEngines) { this.searchEngines = searchEngines; notifyDataSetChanged(); } @@ -90,49 +136,21 @@ public class SearchEngineBar extends Two public View getView(final int position, final View convertView, final ViewGroup parent) { final View view; if (convertView == null) { view = LayoutInflater.from(getContext()).inflate(R.layout.search_engine_bar_item, parent, false); } else { view = convertView; } + view.setLayoutParams(new LayoutParams(iconContainerWidth, ViewGroup.LayoutParams.MATCH_PARENT)); + final ImageView faviconView = (ImageView) view.findViewById(R.id.search_engine_icon); final SearchEngine searchEngine = searchEngines.get(position); faviconView.setImageBitmap(searchEngine.getIcon()); - final View container = view.findViewById(R.id.search_engine_icon_container); final String desc = getResources().getString(R.string.search_bar_item_desc, searchEngine.getEngineIdentifier()); - container.setContentDescription(desc); + view.setContentDescription(desc); return view; } } - - /** - * A Container to surround the SearchEngineBar. This is necessary so we can draw - * a divider across the entire width of the screen, but have the inner list layout - * not take up the full width of the screen so it can be centered within this container - * if there aren't enough items that it needs to scroll. - * - * Note: a better implementation would have this View inflating an inner layout so - * the containing layout doesn't need two "SearchEngineBar" Views but it wasn't - * worth the refactor time. - */ - @SuppressWarnings("unused") // via XML - public static class SearchEngineBarContainer extends FrameLayout { - private final Paint dividerPaint; - - public SearchEngineBarContainer(final Context context, final AttributeSet attrs) { - super(context, attrs); - - dividerPaint = new Paint(); - dividerPaint.setColor(getResources().getColor(R.color.divider_light)); - } - - @Override - public void onDraw(final Canvas canvas) { - super.onDraw(canvas); - - canvas.drawLine(0, 0, getWidth(), 0, dividerPaint); - } - } }
--- a/mobile/android/base/resources/layout/browser_search.xml +++ b/mobile/android/base/resources/layout/browser_search.xml @@ -14,36 +14,22 @@ android:layout="@layout/home_suggestion_prompt" /> <view class="org.mozilla.gecko.home.BrowserSearch$HomeSearchListView" android:id="@+id/home_list_view" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> - <!-- The window background is set to our desired color, #fff, so - reduce overdraw by not drawing the background. - - Note: this needs to be transparent and not null because we - draw a divider in onDraw. --> - <view class="org.mozilla.gecko.home.SearchEngineBar$SearchEngineBarContainer" + <!-- listSelector is too slow for showing pressed state + so we set the pressed colors on the child. --> + <org.mozilla.gecko.home.SearchEngineBar + android:id="@+id/search_engine_bar" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:background="@android:color/transparent"> - - <!-- We add a marginTop so the outer container can draw a divider. - - listSelector is too slow for showing pressed state - so we set the pressed colors on the child. --> - <org.mozilla.gecko.home.SearchEngineBar - android:id="@+id/search_engine_bar" - android:layout_width="wrap_content" - android:layout_height="48dp" - android:layout_marginTop="1dp" - android:orientation="horizontal" - android:layout_gravity="center_horizontal" - android:choiceMode="singleChoice" - android:listSelector="@android:color/transparent" - android:cacheColorHint="@android:color/transparent"/> - - </view> + android:layout_height="48dp" + android:paddingTop="1dp" + android:orientation="horizontal" + android:layout_gravity="center_horizontal" + android:choiceMode="singleChoice" + android:listSelector="@android:color/transparent" + android:cacheColorHint="@android:color/transparent" /> </LinearLayout>
--- a/mobile/android/base/resources/layout/search_engine_bar_item.xml +++ b/mobile/android/base/resources/layout/search_engine_bar_item.xml @@ -3,22 +3,25 @@ - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> <!-- TwoWayView doesn't let us set the margin around items (except as gecko:itemMargin, but that doesn't increase the hit area) so we have to surround the main View by a ViewGroup to create a pressable margin. Note: the layout_height values are shared with the parent - View (browser_search at the time of this writing). --> + View (browser_search at the time of this writing). + + The actual width of the FrameLayout is calculated at runtime by the + SearchEngineBar class to spread the icons across the device's width. --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/search_engine_icon_container" + android:layout_width="72dp" android:layout_height="match_parent" - android:layout_width="72dp" android:background="@color/pressed_about_page_header_grey"> <!-- Width & height are set to make the Favicons as sharp as possible based on asset size. --> <ImageView android:id="@+id/search_engine_icon" android:layout_width="24dp" android:layout_height="24dp"