Bug 1158295 - Dynamically determine space between search engines in search engine bar. r=mcomella

This commit is contained in:
Sebastian Kaspari 2015-06-04 18:13:07 -07:00
parent f182c06275
commit b5033c860d
3 changed files with 67 additions and 60 deletions

View File

@ -9,16 +9,16 @@ 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;
@ -28,16 +28,34 @@ 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);
@ -63,6 +81,34 @@ public class SearchEngineBar extends TwoWayView
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<>();
@ -95,44 +141,16 @@ public class SearchEngineBar extends TwoWayView
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);
}
}
}

View File

@ -19,31 +19,17 @@
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>

View File

@ -8,12 +8,15 @@
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_height="match_parent"
android:layout_width="72dp"
android:layout_height="match_parent"
android:background="@color/pressed_about_page_header_grey">
<!-- Width & height are set to make the Favicons as sharp as possible