aboutsummaryrefslogtreecommitdiffstats
path: root/main/src
diff options
context:
space:
mode:
authorBananeweizen <bananeweizen@gmx.de>2014-12-20 15:56:48 +0100
committerBananeweizen <bananeweizen@gmx.de>2014-12-20 15:56:48 +0100
commit74daa3ebbf94a66b47149ba0428f2c4af838aa15 (patch)
treead3a3bed847006905f15f88f0c8278257ed2cabf /main/src
parente606e1512d3e600e5beab2442e6095c9d08c989b (diff)
downloadcgeo-74daa3ebbf94a66b47149ba0428f2c4af838aa15.zip
cgeo-74daa3ebbf94a66b47149ba0428f2c4af838aa15.tar.gz
cgeo-74daa3ebbf94a66b47149ba0428f2c4af838aa15.tar.bz2
refactoring: replace dynamically created attribute views
Diffstat (limited to 'main/src')
-rw-r--r--main/src/cgeo/geocaching/AttributesGridAdapter.java79
-rw-r--r--main/src/cgeo/geocaching/CacheDetailActivity.java249
-rw-r--r--main/src/cgeo/geocaching/ui/WrappingGridView.java38
3 files changed, 176 insertions, 190 deletions
diff --git a/main/src/cgeo/geocaching/AttributesGridAdapter.java b/main/src/cgeo/geocaching/AttributesGridAdapter.java
new file mode 100644
index 0000000..fd81339
--- /dev/null
+++ b/main/src/cgeo/geocaching/AttributesGridAdapter.java
@@ -0,0 +1,79 @@
+package cgeo.geocaching;
+
+import cgeo.geocaching.enumerations.CacheAttribute;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import java.util.List;
+
+public class AttributesGridAdapter extends BaseAdapter {
+ private final Context context;
+ private final Resources resources;
+ private final List<String> attributes;
+ private final LayoutInflater inflater;
+
+ public AttributesGridAdapter(final Context context, final Geocache cache) {
+ this.context = context;
+ resources = context.getResources();
+ attributes = cache.getAttributes();
+ inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ }
+
+ @Override
+ public int getCount() {
+ return attributes.size();
+ }
+
+ @Override
+ public Object getItem(final int position) {
+ return attributes.get(position);
+ }
+
+ @Override
+ public long getItemId(final int position) {
+ return 0;
+ }
+
+ @Override
+ public View getView(final int position, final View convertView, final ViewGroup parent) {
+ final FrameLayout attributeLayout;
+ if (convertView == null) {
+ attributeLayout = (FrameLayout) inflater.inflate(R.layout.attribute_image, parent, false);
+ } else {
+ attributeLayout = (FrameLayout) convertView;
+ }
+
+ drawAttribute(attributeLayout, attributes.get(position));
+ return attributeLayout;
+ }
+
+ private void drawAttribute(final FrameLayout attributeLayout, final String attributeName) {
+ final ImageView imageView = (ImageView) attributeLayout.getChildAt(0);
+
+ final boolean strikeThrough = !CacheAttribute.isEnabled(attributeName);
+ final CacheAttribute attrib = CacheAttribute.getByRawName(CacheAttribute.trimAttributeName(attributeName));
+ if (attrib != null) {
+ Drawable drawable = resources.getDrawable(attrib.drawableId);
+ imageView.setImageDrawable(drawable);
+ if (strikeThrough) {
+ // generate strike through image with same properties as attribute image
+ final ImageView strikeThroughImage = new ImageView(context);
+ strikeThroughImage.setLayoutParams(imageView.getLayoutParams());
+ drawable = resources.getDrawable(R.drawable.attribute__strikethru);
+ strikeThroughImage.setImageDrawable(drawable);
+ attributeLayout.addView(strikeThroughImage);
+ }
+ } else {
+ imageView.setImageDrawable(resources.getDrawable(R.drawable.attribute_unknown));
+ }
+ }
+
+} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/CacheDetailActivity.java b/main/src/cgeo/geocaching/CacheDetailActivity.java
index e74b2d2..901b2b5 100644
--- a/main/src/cgeo/geocaching/CacheDetailActivity.java
+++ b/main/src/cgeo/geocaching/CacheDetailActivity.java
@@ -12,7 +12,6 @@ import cgeo.geocaching.activity.Progress;
import cgeo.geocaching.apps.cache.navi.NavigationAppFactory;
import cgeo.geocaching.apps.cache.navi.NavigationSelectionActionProvider;
import cgeo.geocaching.apps.cachelist.MapsWithMeCacheListApp;
-import cgeo.geocaching.compatibility.Compatibility;
import cgeo.geocaching.connector.ConnectorFactory;
import cgeo.geocaching.connector.IConnector;
import cgeo.geocaching.connector.gc.GCConnector;
@@ -105,13 +104,11 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.view.ViewParent;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
-import android.widget.FrameLayout;
+import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
@@ -722,185 +719,6 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
}
}
- private class AttributeViewBuilder {
- private ViewGroup attributeIconsLayout; // layout for attribute icons
- private ViewGroup attributeDescriptionsLayout; // layout for attribute descriptions
- private boolean attributesShowAsIcons = true; // default: show icons
- /**
- * If the cache is from a non GC source, it might be without icons. Disable switching in those cases.
- */
- private boolean noAttributeIconsFound = false;
- private int attributeBoxMaxWidth;
-
- public void fillView(final LinearLayout attributeBox) {
- // first ensure that the view is empty
- attributeBox.removeAllViews();
-
- // maximum width for attribute icons is screen width - paddings of parents
- attributeBoxMaxWidth = Compatibility.getDisplayWidth();
- ViewParent child = attributeBox;
- do {
- if (child instanceof View) {
- attributeBoxMaxWidth -= ((View) child).getPaddingLeft() + ((View) child).getPaddingRight();
- }
- child = child.getParent();
- } while (child != null);
-
- // delete views holding description / icons
- attributeDescriptionsLayout = null;
- attributeIconsLayout = null;
-
- attributeBox.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(final View v) {
- // toggle between attribute icons and descriptions
- toggleAttributeDisplay(attributeBox, attributeBoxMaxWidth);
- }
- });
-
- // icons or text?
- //
- // also show icons when noAttributeImagesFound == true. Explanation:
- // 1. no icons could be found in the first invocation of this method
- // 2. user refreshes cache from web
- // 3. now this method is called again
- // 4. attributeShowAsIcons is false but noAttributeImagesFound is true
- // => try to show them now
- if (attributesShowAsIcons || noAttributeIconsFound) {
- showAttributeIcons(attributeBox, attributeBoxMaxWidth);
- } else {
- showAttributeDescriptions(attributeBox);
- }
- }
-
- /**
- * lazy-creates the layout holding the icons of the caches attributes
- * and makes it visible
- */
- private void showAttributeIcons(final LinearLayout attribBox, final int parentWidth) {
- if (attributeIconsLayout == null) {
- attributeIconsLayout = createAttributeIconsLayout(parentWidth);
- // no matching icons found? show text
- if (noAttributeIconsFound) {
- showAttributeDescriptions(attribBox);
- return;
- }
- }
- attribBox.removeAllViews();
- attribBox.addView(attributeIconsLayout);
- attributesShowAsIcons = true;
- }
-
- /**
- * lazy-creates the layout holding the descriptions of the caches attributes
- * and makes it visible
- */
- private void showAttributeDescriptions(final LinearLayout attribBox) {
- if (attributeDescriptionsLayout == null) {
- attributeDescriptionsLayout = createAttributeDescriptionsLayout(attribBox);
- }
- attribBox.removeAllViews();
- attribBox.addView(attributeDescriptionsLayout);
- attributesShowAsIcons = false;
- }
-
- /**
- * toggle attribute descriptions and icons
- */
- private void toggleAttributeDisplay(final LinearLayout attribBox, final int parentWidth) {
- // Don't toggle when there are no icons to show.
- if (noAttributeIconsFound) {
- return;
- }
-
- // toggle
- if (attributesShowAsIcons) {
- showAttributeDescriptions(attribBox);
- } else {
- showAttributeIcons(attribBox, parentWidth);
- }
- }
-
- private ViewGroup createAttributeIconsLayout(final int parentWidth) {
- final LinearLayout rows = new LinearLayout(CacheDetailActivity.this);
- rows.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
- rows.setOrientation(LinearLayout.VERTICAL);
-
- LinearLayout attributeRow = newAttributeIconsRow();
- rows.addView(attributeRow);
-
- noAttributeIconsFound = true;
-
- for (final String attributeName : cache.getAttributes()) {
- // check if another attribute icon fits in this row
- attributeRow.measure(0, 0);
- final int rowWidth = attributeRow.getMeasuredWidth();
- final FrameLayout fl = (FrameLayout) getLayoutInflater().inflate(R.layout.attribute_image, attributeRow, false);
- final ImageView iv = (ImageView) fl.getChildAt(0);
- if ((parentWidth - rowWidth) < iv.getLayoutParams().width) {
- // make a new row
- attributeRow = newAttributeIconsRow();
- rows.addView(attributeRow);
- }
-
- final boolean strikeThrough = !CacheAttribute.isEnabled(attributeName);
- final CacheAttribute attrib = CacheAttribute.getByRawName(CacheAttribute.trimAttributeName(attributeName));
- if (attrib != null) {
- noAttributeIconsFound = false;
- Drawable drawable = res.getDrawable(attrib.drawableId);
- iv.setImageDrawable(drawable);
- // strike through?
- if (strikeThrough) {
- // generate strike through image with same properties as attribute image
- final ImageView strikeThroughImage = new ImageView(CacheDetailActivity.this);
- strikeThroughImage.setLayoutParams(iv.getLayoutParams());
- drawable = res.getDrawable(R.drawable.attribute__strikethru);
- strikeThroughImage.setImageDrawable(drawable);
- fl.addView(strikeThroughImage);
- }
- } else {
- iv.setImageDrawable(res.getDrawable(R.drawable.attribute_unknown));
- }
-
- attributeRow.addView(fl);
- }
-
- return rows;
- }
-
- private LinearLayout newAttributeIconsRow() {
- final LinearLayout rowLayout = new LinearLayout(CacheDetailActivity.this);
- rowLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
- LayoutParams.WRAP_CONTENT));
- rowLayout.setOrientation(LinearLayout.HORIZONTAL);
- return rowLayout;
- }
-
- private ViewGroup createAttributeDescriptionsLayout(final LinearLayout parentView) {
- final LinearLayout descriptions = (LinearLayout) getLayoutInflater().inflate(
- R.layout.attribute_descriptions, parentView, false);
- final TextView attribView = (TextView) descriptions.getChildAt(0);
-
- final StringBuilder buffer = new StringBuilder();
- for (String attributeName : cache.getAttributes()) {
- final boolean enabled = CacheAttribute.isEnabled(attributeName);
- // search for a translation of the attribute
- final CacheAttribute attrib = CacheAttribute.getByRawName(CacheAttribute.trimAttributeName(attributeName));
- if (attrib != null) {
- attributeName = attrib.getL10n(enabled);
- }
- if (buffer.length() > 0) {
- buffer.append('\n');
- }
- buffer.append(attributeName);
- }
-
- attribView.setText(buffer);
-
- return descriptions;
- }
- }
-
private void refreshCache() {
if (progress.isShowing()) {
showToast(res.getString(R.string.err_detail_still_working));
@@ -1043,11 +861,8 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
}
// cache attributes
- if (!cache.getAttributes().isEmpty()) {
- final LinearLayout innerLayout = ButterKnife.findById(view, R.id.attributes_innerbox);
- new AttributeViewBuilder().fillView(innerLayout);
- view.findViewById(R.id.attributes_box).setVisibility(View.VISIBLE);
- }
+ updateAttributesText();
+ updateAttributesIcons();
updateOfflineBox(view, cache, res, new RefreshCacheClickListener(), new DropCacheClickListener(), new StoreCacheClickListener());
@@ -1086,6 +901,61 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
return view;
}
+ private void updateAttributesIcons() {
+ final GridView gridView = ButterKnife.findById(view, R.id.attributes_grid);
+ final List<String> attributes = cache.getAttributes();
+ if (attributes.isEmpty()) {
+ gridView.setVisibility(View.GONE);
+ return;
+ }
+ gridView.setAdapter(new AttributesGridAdapter(CacheDetailActivity.this, cache));
+ gridView.setVisibility(View.VISIBLE);
+ gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(final android.widget.AdapterView<?> parent, final View view, final int position, final long id) {
+ toggleAttributesView();
+ }
+ });
+ }
+
+ protected void toggleAttributesView() {
+ final View textView = ButterKnife.findById(view, R.id.attributes_text);
+ textView.setVisibility(textView.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
+ final View gridView = ButterKnife.findById(view, R.id.attributes_grid);
+ gridView.setVisibility(gridView.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
+ }
+
+ private void updateAttributesText() {
+ final TextView attribView = ButterKnife.findById(view, R.id.attributes_text);
+ final List<String> attributes = cache.getAttributes();
+ if (attributes.isEmpty()) {
+ attribView.setVisibility(View.GONE);
+ return;
+ }
+ final StringBuilder text = new StringBuilder();
+ for (String attributeName : attributes) {
+ final boolean enabled = CacheAttribute.isEnabled(attributeName);
+ // search for a translation of the attribute
+ final CacheAttribute attrib = CacheAttribute.getByRawName(CacheAttribute.trimAttributeName(attributeName));
+ if (attrib != null) {
+ attributeName = attrib.getL10n(enabled);
+ }
+ if (text.length() > 0) {
+ text.append('\n');
+ }
+ text.append(attributeName);
+ }
+ attribView.setText(text);
+ attribView.setVisibility(View.GONE);
+ attribView.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(final View v) {
+ toggleAttributesView();
+ }
+ });
+ }
+
private class StoreCacheClickListener implements View.OnClickListener {
@Override
public void onClick(final View arg0) {
@@ -1304,11 +1174,10 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
buttonRemove.setEnabled(false);
buttonRemove.setVisibility(View.GONE);
}
-
}
/**
- * Show/hide buttons, set text in favourite line and box
+ * Show/hide buttons, set text in favorite line and box
*/
private void updateFavPointBox() {
// Favorite counts
diff --git a/main/src/cgeo/geocaching/ui/WrappingGridView.java b/main/src/cgeo/geocaching/ui/WrappingGridView.java
new file mode 100644
index 0000000..2c85887
--- /dev/null
+++ b/main/src/cgeo/geocaching/ui/WrappingGridView.java
@@ -0,0 +1,38 @@
+package cgeo.geocaching.ui;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.GridView;
+
+/**
+ * GridView that will adjust its height to really use wrap_content. The standard GridView only shows one line of items.
+ *
+ * @see <a href="https://gist.github.com/runemart/9781609">https://gist.github.com/runemart/9781609</a>
+ *
+ */
+public class WrappingGridView extends GridView {
+
+ public WrappingGridView(final Context context) {
+ super(context);
+ }
+
+ public WrappingGridView(final Context context, final AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public WrappingGridView(final Context context, final AttributeSet attrs, final int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
+ int heightSpec = heightMeasureSpec;
+ if (getLayoutParams().height == android.view.ViewGroup.LayoutParams.WRAP_CONTENT) {
+ // The two leftmost bits in the height measure spec have
+ // a special meaning, hence we can't use them to describe height.
+ heightSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
+ }
+ super.onMeasure(widthMeasureSpec, heightSpec);
+ }
+
+} \ No newline at end of file