Caching images in AsyncImageView

pull/14/head
Andrew Shaw 13 years ago
parent 599e7b7561
commit 2a01d8460d

@ -203,8 +203,4 @@ public final class TagData extends RemoteModel {
return getValue(DELETION_DATE) > 0;
}
public String getPictureHash() {
return getId() + "" + getValue(TagData.CREATION_DATE);
}
}

@ -162,8 +162,4 @@ public class Update extends RemoteModel {
return CREATOR;
}
public String getPictureHash() {
String s = getValue(Update.TASK) + "" + getValue(Update.CREATION_DATE);
return s;
}
}

@ -1,7 +1,5 @@
package com.todoroo.astrid.actfm;
import greendroid.widget.AsyncImageView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@ -50,6 +48,7 @@ import com.todoroo.astrid.actfm.sync.ActFmSyncService;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.TagData;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.helper.AsyncImageView;
import com.todoroo.astrid.service.AstridDependencyInjector;
import com.todoroo.astrid.service.MetadataService;
import com.todoroo.astrid.service.TagDataService;

@ -1,7 +1,5 @@
package com.todoroo.astrid.actfm;
import greendroid.widget.AsyncImageView;
import java.io.IOException;
import org.json.JSONArray;
@ -24,10 +22,11 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
import com.timsu.astrid.R;
import com.todoroo.andlib.service.Autowired;
@ -46,6 +45,7 @@ import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.core.PluginServices;
import com.todoroo.astrid.data.TagData;
import com.todoroo.astrid.helper.AsyncImageView;
import com.todoroo.astrid.helper.ImageDiskCache;
import com.todoroo.astrid.service.StatisticsConstants;
import com.todoroo.astrid.service.StatisticsService;
@ -84,7 +84,7 @@ public class TagSettingsActivity extends FragmentActivity {
private AsyncImageView picture;
private EditText tagName;
private EditText tagDescription;
private ToggleButton isSilent;
private CheckBox isSilent;
private Bitmap setBitmap;
private final ImageDiskCache imageCache;
@ -173,7 +173,7 @@ public class TagSettingsActivity extends FragmentActivity {
tagName = (EditText) findViewById(R.id.tag_name);
tagDescription = (EditText) findViewById(R.id.tag_description);
picture = (AsyncImageView) findViewById(R.id.picture);
isSilent = (ToggleButton) findViewById(R.id.tag_silenced);
isSilent = (CheckBox) findViewById(R.id.tag_silenced);
isSilent.setChecked(tagData.getFlag(TagData.FLAGS, TagData.FLAG_SILENT));
Button leaveListButton = (Button) findViewById(R.id.leave_list);
@ -205,12 +205,13 @@ public class TagSettingsActivity extends FragmentActivity {
if (isNewTag) {
findViewById(R.id.create_shortcut_container).setVisibility(View.GONE);
} else {
findViewById(R.id.create_shortcut).setOnClickListener(new OnClickListener() {
findViewById(R.id.create_shortcut_container).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (filter == null) {
filter = TagFilterExposer.filterFromTagData(TagSettingsActivity.this, tagData);
}
filter.listingIcon = picture.getImageBitmap();
FilterListFragment.showCreateShortcutDialog(TagSettingsActivity.this, ShortcutActivity.createIntent(filter), filter);
}
});
@ -334,8 +335,7 @@ public class TagSettingsActivity extends FragmentActivity {
public void run() {
actFmSyncService.pushTagDataOnSave(tagData, tagData.getMergedValues());
if(setBitmap != null && tagData.getValue(TagData.REMOTE_ID) > 0)
uploadTagPicture(setBitmap);
uploadTagPicture(setBitmap);
runOnUiThread(loadTag);
}
@ -357,7 +357,7 @@ public class TagSettingsActivity extends FragmentActivity {
private void saveTagPictureLocally(Bitmap bitmap) {
if (bitmap == null) return;
try {
String tagPicture = tagData.getPictureHash();
String tagPicture = ImageDiskCache.getPictureHash(tagData);
imageCache.put(tagPicture, bitmap);
tagData.setValue(TagData.PICTURE, tagPicture);
}
@ -397,18 +397,11 @@ public class TagSettingsActivity extends FragmentActivity {
setTitle(getString(R.string.tag_settings_title));
}
}
String tagImage = tagData.getValue(TagData.PICTURE);
if(!TextUtils.isEmpty(tagImage) && imageCache.contains(tagImage)) {
try {
picture.setDefaultImageBitmap(imageCache.get(tagImage));
} catch (IOException e) {
e.printStackTrace();
}
}
else {
picture.setUrl(tagImage);
}
picture.setUrl(tagData.getValue(TagData.PICTURE));
if (!isNewTag) {
ImageView shortcut = (ImageView) findViewById(R.id.create_shortcut);
shortcut.setImageBitmap(FilterListFragment.superImposeListIcon(this, picture.getImageBitmap(), tagData.getValue(TagData.NAME)));
}
String peopleJson = tagData.getValue(TagData.MEMBERS);
updateMembers(peopleJson);
@ -438,6 +431,10 @@ public class TagSettingsActivity extends FragmentActivity {
public void run() {
try {
String url = actFmSyncService.setTagPicture(tagData.getValue(TagData.REMOTE_ID), bitmap);
if (TextUtils.isEmpty(url)) return;
if (imageCache.contains(tagData.getValue(TagData.PICTURE))) {
imageCache.move(tagData.getValue(TagData.PICTURE), url);
}
tagData.setValue(TagData.PICTURE, url);
Flags.set(Flags.ACTFM_SUPPRESS_SYNC);
tagDataService.save(tagData);
@ -510,39 +507,37 @@ public class TagSettingsActivity extends FragmentActivity {
protected void showDeleteDialog(TagData tagData) {
int string;
if (tagData != null && tagData.getValue(TagData.MEMBER_COUNT) > 0)
string = R.string.DLG_leave_this_shared_tag_question;
else
string = R.string.DLG_delete_this_tag_question;
DialogUtilities.okCancelDialog(this, getString(string, tagData.getValue(TagData.NAME)), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
deleteTag();
}
}, null );
}
protected void showDeleteDialog(TagData tagData) {
int string;
if (tagData != null && tagData.getValue(TagData.MEMBER_COUNT) > 0)
string = R.string.DLG_leave_this_shared_tag_question;
else
string = R.string.DLG_delete_this_tag_question;
DialogUtilities.okCancelDialog(this, getString(string, tagData.getValue(TagData.NAME)), new DialogInterface.OnClickListener() {
protected boolean deleteTag() {
tagDataService.delete(tagData.getId());
boolean shared = false;
if(tagData != null) {
tagData.setValue(TagData.DELETION_DATE, DateUtilities.now());
PluginServices.getTagDataService().save(tagData);
shared = tagData.getValue(TagData.MEMBER_COUNT) > 0 && tagData.getValue(TagData.USER_ID) != 0; // Was I a list member and NOT owner?
@Override
public void onClick(DialogInterface dialog, int which) {
deleteTag();
}
}, null );
}
Intent tagDeleted = new Intent(AstridApiConstants.BROADCAST_EVENT_TAG_DELETED);
tagDeleted.putExtra(TagViewFragment.EXTRA_TAG_NAME, tagData.getValue(TagData.NAME));
tagDeleted.putExtra(TagFilterExposer.TAG_SQL, TagFilterExposer.SHOW_ACTIVE_TASKS);
protected boolean deleteTag() {
tagDataService.delete(tagData.getId());
if(tagData != null) {
tagData.setValue(TagData.DELETION_DATE, DateUtilities.now());
PluginServices.getTagDataService().save(tagData);
}
this.finish();
sendBroadcast(tagDeleted);
Intent tagDeleted = new Intent(AstridApiConstants.BROADCAST_EVENT_TAG_DELETED);
tagDeleted.putExtra(TagViewFragment.EXTRA_TAG_NAME, tagData.getValue(TagData.NAME));
tagDeleted.putExtra(TagFilterExposer.TAG_SQL, TagFilterExposer.SHOW_ACTIVE_TASKS);
return true;
}
this.finish();
sendBroadcast(tagDeleted);
return true;
}

@ -1,6 +1,6 @@
package com.todoroo.astrid.actfm;
import greendroid.widget.AsyncImageView;
import com.todoroo.astrid.helper.AsyncImageView;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;

@ -1,6 +1,6 @@
package com.todoroo.astrid.actfm;
import greendroid.widget.AsyncImageView;
import com.todoroo.astrid.helper.AsyncImageView;
import org.json.JSONArray;
import org.json.JSONException;

@ -26,9 +26,9 @@ import com.todoroo.andlib.utility.Preferences;
public class ActFmInvoker {
/** NOTE: these values are development values & will not work on production */
private static final String URL = "//astrid.com/api/";
private static final String APP_ID = "bf6170638298af8ed9a8c79995b1fc0f";
private static final String APP_SECRET = "d15d25c63323bddcaa48928dccac1207";
private static final String URL = "//10.0.2.2:3000/api/";
private static final String APP_ID = "a4732a32859dbcd3e684331acd36432c";
private static final String APP_SECRET = "e389bfc82a0d932332f9a8bd8203735f";
public static final String PROVIDER_FACEBOOK = "facebook";
public static final String PROVIDER_GOOGLE= "google";

@ -1,8 +1,5 @@
package com.todoroo.astrid.notes;
import greendroid.widget.AsyncImageView;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@ -58,6 +55,7 @@ import com.todoroo.astrid.dao.UpdateDao;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.Update;
import com.todoroo.astrid.helper.AsyncImageView;
import com.todoroo.astrid.helper.ImageDiskCache;
import com.todoroo.astrid.helper.ProgressBarSyncResultCallback;
import com.todoroo.astrid.service.MetadataService;
@ -367,16 +365,7 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
commentPictureView.setVisibility(View.GONE);
else {
commentPictureView.setVisibility(View.VISIBLE);
if(imageCache.contains(item.commentPicture)) {
try {
commentPictureView.setDefaultImageBitmap(imageCache.get(item.commentPicture));
} catch (IOException e) {
e.printStackTrace();
}
}
else {
commentPictureView.setUrl(item.commentPicture);
}
commentPictureView.setUrl(item.commentPicture);
}
}
}
@ -445,7 +434,7 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
if (usePicture && pendingCommentPicture != null) {
update.setValue(Update.PICTURE, Update.PICTURE_LOADING);
try {
String updateString = update.getPictureHash();
String updateString = ImageDiskCache.getPictureHash(update);
imageCache.put(updateString, pendingCommentPicture);
update.setValue(Update.PICTURE, updateString);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 B

After

Width:  |  Height:  |  Size: 508 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

@ -5,7 +5,7 @@
android:layout_height="fill_parent"
android:paddingLeft="8dip">
<greendroid.widget.AsyncImageView android:id="@+id/person_image"
<com.todoroo.astrid.helper.AsyncImageView android:id="@+id/person_image"
android:layout_width="40dip"
android:layout_height="44dip"
android:gravity="center"

@ -10,7 +10,7 @@
android:orientation="horizontal">
<!-- picture thumbnail -->
<greendroid.widget.AsyncImageView android:id="@+id/icon"
<com.todoroo.astrid.helper.AsyncImageView android:id="@+id/icon"
android:layout_width="40dip"
android:layout_height="44dip"
android:gravity="center"

@ -25,13 +25,13 @@
android:layout_height="wrap_content"
android:orientation="horizontal" >
<greendroid.widget.AsyncImageView
<com.todoroo.astrid.helper.AsyncImageView
android:id="@+id/icon"
android:layout_width="31dip"
android:layout_height="35dip"
android:layout_margin="5dip"
astrid:defaultSrc="@drawable/icn_default_person_image"
android:gravity="center"
android:layout_margin="5dip"
android:scaleType="fitCenter" />
<com.todoroo.astrid.ui.ContactsAutoComplete
@ -39,11 +39,13 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:layout_marginLeft="5dip"
android:layout_weight="1"
android:background="#00000000"
android:hint="@string/actfm_person_hint"
android:textColor="@android:color/black" />
style="@style/TextAppearance"
android:textCursorDrawable="@null"
android:textSize="15sp" />
<ImageButton
android:id="@+id/button1"

@ -21,7 +21,7 @@
android:visibility="gone"/>
<!-- filter url image icon -->
<greendroid.widget.AsyncImageView android:id="@+id/url_image"
<com.todoroo.astrid.helper.AsyncImageView android:id="@+id/url_image"
android:layout_width="30dip"
android:layout_height="48dip"
android:layout_alignParentLeft="true"

@ -1,202 +1,229 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:astrid="http://schemas.android.com/apk/res/com.timsu.astrid"
android:id="@+id/settings"
style="@style/Content_EditScroll"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="100" >
<LinearLayout
<ScrollView
android:id="@+id/settings"
style="@style/Content_EditScroll"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5dip"
android:layout_height="fill_parent"
android:layout_weight="100"
android:padding="10dip"
android:paddingTop="0dip" >
<LinearLayout
android:id="@+id/save_and_cancel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:orientation="horizontal"
android:visibility="gone" >
android:orientation="vertical" >
<ImageButton
android:id="@+id/cancel"
android:layout_width="wrap_content"
<LinearLayout
android:id="@+id/save_and_cancel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginRight="10dip"
android:background="@android:color/transparent"
android:src="@android:drawable/ic_menu_close_clear_cancel" />
android:gravity="right"
android:orientation="horizontal"
android:visibility="gone" >
<ImageButton
android:id="@+id/save"
android:layout_width="wrap_content"
<ImageButton
android:id="@+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dip"
android:background="@android:color/transparent"
android:src="@android:drawable/ic_menu_close_clear_cancel" />
<ImageButton
android:id="@+id/save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dip"
android:background="@android:color/transparent"
android:src="@android:drawable/ic_menu_save" />
</LinearLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginRight="10dip"
android:background="@android:color/transparent"
android:src="@android:drawable/ic_menu_save" />
</LinearLayout>
android:paddingBottom="5dip"
android:paddingTop="5dip" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="5dip"
android:paddingTop="5dip" >
<!-- picture -->
<!-- picture -->
<com.todoroo.astrid.helper.AsyncImageView
android:id="@+id/picture"
android:layout_width="80dip"
android:layout_height="80dip"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
astrid:defaultSrc="@android:drawable/ic_menu_gallery"
android:scaleType="centerCrop" />
<greendroid.widget.AsyncImageView
android:id="@+id/picture"
android:layout_width="80dip"
android:layout_height="80dip"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
astrid:defaultSrc="@android:drawable/ic_menu_gallery"
android:paddingRight="10dip"
android:scaleType="centerInside" />
<TextView
android:id="@+id/tag_label"
style="@style/TextAppearance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginLeft="10dip"
android:layout_toRightOf="@id/picture"
android:text="@string/actfm_TVA_tag_label" />
<LinearLayout
style="@style/EditRow"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tag_label"
android:layout_marginLeft="10dip"
android:layout_marginTop="14dip"
android:layout_toRightOf="@id/picture"
android:padding="10dip"
android:paddingBottom="14dip" >
<EditText
android:id="@+id/tag_name"
style="@style/TextAppearance"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#00000000"
android:hint="@string/actfm_TVA_tag_description_hint"
android:singleLine="true"
android:textCursorDrawable="@null"
android:textSize="15sp" />
</LinearLayout>
</RelativeLayout>
<TextView
android:id="@+id/tag_label"
style="@style/TextAppearance"
android:layout_width="wrap_content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="2dip"
android:layout_toRightOf="@id/picture"
android:text="@string/actfm_TVA_tag_label" />
android:layout_marginLeft="10dip"
android:layout_marginTop="10dip"
android:paddingBottom="5dip"
android:text="@string/actfm_TVA_members_label" />
<EditText
android:id="@+id/tag_name"
<com.todoroo.astrid.ui.PeopleContainer
android:id="@+id/members_container"
style="@style/EditRow"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tag_label"
android:layout_marginTop="10dip"
android:layout_toRightOf="@id/picture"
android:maxLines="1"
android:padding="10dip"
android:paddingBottom="14dip" />
</RelativeLayout>
<TextView
style="@style/TextAppearance"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:layout_marginTop="10dip"
android:paddingBottom="5dip"
android:text="@string/actfm_TVA_members_label" />
<com.todoroo.astrid.ui.PeopleContainer
android:id="@+id/members_container"
style="@style/EditRow"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
<TextView
android:id="@+id/description_label"
style="@style/TextAppearance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:layout_marginTop="10dip"
android:text="@string/actfm_TVA_tag_description_label" />
<EditText
android:id="@+id/tag_description"
style="@style/EditRow"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dip"
android:hint="@string/actfm_TVA_tag_description_hint"
android:padding="8dip"
android:paddingBottom="12dip" />
<!-- Footer -->
android:orientation="vertical" />
<TextView
android:id="@+id/settings_label"
style="@style/TextAppearance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:layout_marginTop="10dip"
android:text="@string/actfm_TVA_tag_settings_label" />
<LinearLayout
style="@style/EditRow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dip"
android:orientation="vertical" >
<TextView
android:id="@+id/description_label"
style="@style/TextAppearance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:layout_marginTop="10dip"
android:text="@string/actfm_TVA_tag_description_label" />
<RelativeLayout
android:id="@+id/tag_silenced_container"
<LinearLayout
style="@style/EditRow"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
android:layout_below="@id/tag_label"
android:layout_marginTop="5dip"
android:padding="10dip"
android:paddingBottom="14dip" >
<TextView
<EditText
android:id="@+id/tag_description"
style="@style/TextAppearance"
android:layout_width="wrap_content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginTop="10dip"
android:padding="5dip"
android:text="@string/actfm_TVA_silence_label" />
android:background="#00000000"
android:hint="@string/actfm_TVA_tag_description_hint"
android:textCursorDrawable="@null"
android:textSize="15sp" />
</LinearLayout>
<ToggleButton
android:id="@+id/tag_silenced"
style="@style/TextAppearance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:paddingRight="5dip" />
</RelativeLayout>
<!-- Footer -->
<View
android:id="@+id/divider"
style="@style/TEA_Separator"
android:layout_width="fill_parent"
android:layout_height="1dip" />
<TextView
android:id="@+id/settings_label"
style="@style/TextAppearance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:layout_marginTop="10dip"
android:text="@string/actfm_TVA_tag_settings_label" />
<RelativeLayout
android:id="@+id/create_shortcut_container"
android:layout_width="fill_parent"
<LinearLayout
style="@style/EditRow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dip" >
android:layout_marginTop="5dip"
android:orientation="vertical" >
<TextView
style="@style/TextAppearance"
android:layout_width="wrap_content"
<RelativeLayout
android:id="@+id/tag_silenced_container"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginTop="10dip"
android:text="@string/FLA_shortcut_dialog_title" />
<ImageButton
android:id="@+id/create_shortcut"
android:layout_width="40dip"
android:layout_height="40dip"
android:layout_alignParentRight="true"
android:background="@android:color/transparent"
android:scaleType="fitCenter"
android:src="@drawable/icn_list_shortcut" />
</RelativeLayout>
android:orientation="horizontal"
android:padding="5dip" >
<TextView
style="@style/TextAppearance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginTop="10dip"
android:paddingLeft="5dip"
android:text="@string/actfm_TVA_silence_label" />
<CheckBox
android:id="@+id/tag_silenced"
style="@style/TextAppearance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:paddingRight="5dip" />
</RelativeLayout>
<View
android:id="@+id/divider"
style="@style/TEA_Separator"
android:layout_width="fill_parent"
android:layout_height="1dip" />
<RelativeLayout
android:id="@+id/create_shortcut_container"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dip" >
<TextView
style="@style/TextAppearance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginTop="10dip"
android:paddingLeft="5dip"
android:text="@string/FLA_shortcut_dialog_title" />
<ImageButton
android:id="@+id/create_shortcut"
android:layout_width="40dip"
android:layout_height="40dip"
android:layout_alignParentRight="true"
android:background="@android:color/transparent"
android:scaleType="fitCenter"
android:src="@drawable/icn_list_shortcut" />
</RelativeLayout>
</LinearLayout>
<Button
android:id="@+id/leave_list"
style="@style/DeleteTag"
android:layout_width="fill_parent"
android:layout_height="40dip"
android:layout_marginTop="15dip"
android:text="@string/tag_delete_button" />
</LinearLayout>
</ScrollView>
<Button
android:id="@+id/leave_list"
style="@style/DeleteTag"
android:layout_width="fill_parent"
android:layout_height="40dip"
android:layout_marginTop="10dip"
android:padding="5dip"
android:text="@string/tag_delete_button" />
</LinearLayout>
</ScrollView>
</LinearLayout>

@ -79,4 +79,4 @@
android:scaleType="center" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

@ -18,7 +18,7 @@
android:layout_height="wrap_content"
android:orientation="horizontal" >
<greendroid.widget.AsyncImageView
<com.todoroo.astrid.helper.AsyncImageView
android:id="@+id/tag_picture"
android:layout_width="80dip"
android:layout_height="80dip"

@ -0,0 +1,127 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- See the file "LICENSE" for the full license governing this code. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:astrid="http://schemas.android.com/apk/res/com.timsu.astrid"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="57dip"
android:paddingTop="2dip"
android:paddingBottom="2dip"
android:gravity="center_vertical"
android:orientation="horizontal">
<View
android:id="@+id/importance_legacy"
android:layout_width="4dip"
android:layout_height="fill_parent"
android:visibility="gone" />
<!-- indent -->
<View android:id="@+id/indent"
android:layout_width="0dip"
android:layout_height="fill_parent"/>
<!-- grabber -->
<ImageView android:id="@+id/grabber"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:scaleType="center"
android:src="@drawable/grabber"/>
<RelativeLayout android:id="@+id/rowBody"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:drawable/list_selector_background"
android:layout_marginTop="6dip"
android:layout_marginBottom="6dip"
android:paddingLeft="5dip">
<com.todoroo.astrid.ui.CheckableImageView
android:id="@+id/completeBox"
android:layout_width="45dip"
android:layout_height="wrap_content"
android:minHeight="30dip"
android:scaleType="center"
android:layout_alignParentTop="true"
android:layout_marginLeft="2dip"
android:button="@drawable/btn_check" />
<!-- assignee photo -->
<com.todoroo.astrid.helper.AsyncImageView
android:id="@+id/picture"
android:layout_width="35dip"
android:layout_height="35dip"
android:layout_marginLeft="10dip"
astrid:defaultSrc="@drawable/icn_default_person_image"
android:scaleType="fitCenter"
android:visibility="gone" />
<LinearLayout
android:id="@+id/task_row"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/completeBox"
android:layout_centerVertical="true"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingLeft="5dip" >
<!-- task name -->
<TextView
android:id="@+id/title"
style="@style/TextAppearance.TAd_ItemTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="100"
android:gravity="center_vertical"
android:maxLines="2" />
<!-- due date -->
<LinearLayout
android:id="@+id/taskActionContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="40dip"
android:layout_marginRight="4dip"
android:orientation="vertical"
android:gravity="right|center_vertical">
<TextView
android:id="@+id/dueDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="4dip"
android:gravity="center_vertical|right" />
<ImageView
android:id="@+id/taskActionIcon"
android:layout_width="20dip"
android:layout_height="20dip"
android:scaleType="fitCenter"
android:visibility="gone"/>
</LinearLayout>
</LinearLayout>
<!-- details line 1 -->
<TextView android:id="@+id/details1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/task_row"
android:layout_alignParentLeft="true"
android:layout_marginTop="-1dip"
style="@style/TextAppearance.TAd_ItemDetails"
android:visibility="gone" />
<!-- details line 2 -->
<TextView android:id="@+id/details2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/details1"
android:layout_alignParentLeft="true"
style="@style/TextAppearance.TAd_ItemDetails"
android:visibility="gone" />
</RelativeLayout>
</LinearLayout>

@ -33,7 +33,7 @@
android:scaleType="center"
android:visibility="gone" >
</ImageView>
<greendroid.widget.AsyncImageView
<com.todoroo.astrid.helper.AsyncImageView
android:id="@+id/picture"
android:layout_width="45dip"
android:layout_height="45dip"
@ -42,8 +42,7 @@
android:layout_centerVertical="true"
astrid:defaultSrc="@drawable/icn_default_person_image"
android:scaleType="fitCenter"
android:visibility="gone" >
</greendroid.widget.AsyncImageView>
android:visibility="gone" />
<com.todoroo.astrid.ui.CheckableImageView
android:id="@+id/completeBox"

@ -16,7 +16,7 @@
android:paddingRight="6dip">
<!-- picture -->
<greendroid.widget.AsyncImageView android:id="@+id/picture"
<com.todoroo.astrid.helper.AsyncImageView android:id="@+id/picture"
android:layout_width="40dip"
android:layout_height="40dip"
android:layout_alignParentTop="true"
@ -52,7 +52,7 @@
<!-- picture -->
<greendroid.widget.AsyncImageView android:id="@+id/comment_picture"
<com.todoroo.astrid.helper.AsyncImageView android:id="@+id/comment_picture"
android:layout_width="100dip"
android:layout_height="100dip"
android:layout_below="@id/date"
@ -66,7 +66,7 @@
</RelativeLayout>
<!-- picture -->
<greendroid.widget.AsyncImageView
<com.todoroo.astrid.helper.AsyncImageView
android:id="@+id/comment_picture"
android:layout_width="50dip"
android:layout_height="50dip"

@ -7,7 +7,7 @@
android:background="@android:drawable/list_selector_background">
<!-- imageview -->
<greendroid.widget.AsyncImageView android:id="@+id/image"
<com.todoroo.astrid.helper.AsyncImageView android:id="@+id/image"
android:layout_width="70dip"
android:layout_height="100dip"
android:layout_marginLeft="5dip"

@ -7,7 +7,7 @@
android:background="@android:drawable/list_selector_background">
<!-- imageview -->
<greendroid.widget.AsyncImageView android:id="@+id/image"
<com.todoroo.astrid.helper.AsyncImageView android:id="@+id/image"
android:layout_width="100dip"
android:layout_height="100dip"
android:layout_marginLeft="5dip"

@ -109,6 +109,9 @@
<!-- Tag Settings: list description hint -->
<string name="actfm_TVA_tag_description_hint">Type a description here</string>
<!-- Tag Settings: list name hint -->
<string name="actfm_TVA_tag_name_hint">Enter list name</string>
<!-- Tag settings: login prompt from share-->
<string name="actfm_TVA_login_to_share">You need to be logged in to Astrid.com to share lists! Please log in or make this a private list.</string>

@ -387,8 +387,9 @@
<!-- ========================================================= Tag Settings == -->
<style name="DeleteTag" >
<item name="android:textColor">?attr/asTextColor</item>
<item name="android:background">?attr/asThemeTextColor</item>
<item name="android:textColor">@android:color/white</item>
<item name="android:textStyle">bold</item>
<item name="android:background">#d90000</item>
</style>
<!-- ========================================================= Widget == -->

@ -365,10 +365,24 @@ public class FilterListFragment extends ListFragment {
if(label.length() == 0)
return;
Bitmap emblem = filter.listingIcon;
Bitmap bitmap = superImposeListIcon(activity, filter.listingIcon, filter.listingTitle);
Intent createShortcutIntent = new Intent();
createShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
createShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, label);
createShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, bitmap);
createShortcutIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT"); //$NON-NLS-1$
activity.sendBroadcast(createShortcutIntent);
Toast.makeText(activity,
activity.getString(R.string.FLA_toast_onCreateShortcut, label), Toast.LENGTH_LONG).show();
}
public static Bitmap superImposeListIcon(Activity activity, Bitmap listingIcon, String listingTitle) {
Bitmap emblem = listingIcon;
if(emblem == null)
emblem = ((BitmapDrawable) activity.getResources().getDrawable(
TagService.getDefaultImageIDForTag(filter.listingTitle))).getBitmap();
TagService.getDefaultImageIDForTag(listingTitle))).getBitmap();
// create icon by superimposing astrid w/ icon
DisplayMetrics metrics = new DisplayMetrics();
@ -381,16 +395,7 @@ public class FilterListFragment extends ListFragment {
canvas.drawBitmap(emblem, new Rect(0, 0, emblem.getWidth(), emblem.getHeight()),
new Rect(bitmap.getWidth() - dimension, bitmap.getHeight() - dimension,
bitmap.getWidth(), bitmap.getHeight()), null);
Intent createShortcutIntent = new Intent();
createShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
createShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, label);
createShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, bitmap);
createShortcutIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT"); //$NON-NLS-1$
activity.sendBroadcast(createShortcutIntent);
Toast.makeText(activity,
activity.getString(R.string.FLA_toast_onCreateShortcut, label), Toast.LENGTH_LONG).show();
return bitmap;
}
@Override

@ -3,7 +3,7 @@
*/
package com.todoroo.astrid.adapter;
import greendroid.widget.AsyncImageView;
import com.todoroo.astrid.helper.AsyncImageView;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;

@ -1,6 +1,6 @@
package com.todoroo.astrid.adapter;
import greendroid.widget.AsyncImageView;
import com.todoroo.astrid.helper.AsyncImageView;
import java.util.Collection;
import java.util.Collections;

@ -1,6 +1,6 @@
package com.todoroo.astrid.adapter;
import greendroid.widget.AsyncImageView;
import com.todoroo.astrid.helper.AsyncImageView;
import java.io.IOException;

@ -0,0 +1,67 @@
package com.todoroo.astrid.helper;
import java.io.IOException;
import android.content.Context;
import android.graphics.Bitmap;
import android.text.TextUtils;
import android.util.AttributeSet;
/*
* Subclass of greendroid.widget.AsyncImageView, so that we can cache the image locally when user is offline
* IMPORTANT: cannot load a cached image by setting the url in an xml file. --ImageDiskCache object is created after object is loaded from xml
*/
public class AsyncImageView extends greendroid.widget.AsyncImageView {
private final ImageDiskCache imageDiskCache;
private Bitmap cacheImage;
private String cacheURL = ""; //$NON-NLS-1$
public AsyncImageView(Context context) {
super(context);
imageDiskCache = ImageDiskCache.getInstance();
}
public AsyncImageView(Context context, AttributeSet set) {
super(context, set);
imageDiskCache = ImageDiskCache.getInstance();
}
public AsyncImageView(Context context, AttributeSet set, int defStyle) {
super(context, set, defStyle);
imageDiskCache = ImageDiskCache.getInstance();
}
@Override
public void setUrl(String url) {
if (cacheImage != null && cacheURL.equals(url) && !TextUtils.isEmpty(url)) {
setImageBitmap(cacheImage);
return;
}
else if(imageDiskCache != null && imageDiskCache.contains(url)) {
try {
cacheImage = imageDiskCache.get(url);
setImageBitmap(cacheImage);
cacheURL = url;
return;
} catch (IOException e) {
//
}
}
super.setUrl(url);
}
public Bitmap getImageBitmap() {
setDrawingCacheEnabled(true);
// this is the important code :)
// Without it the view will have a dimension of 0,0 and the bitmap will be null
measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
layout(0, 0, getMeasuredWidth(), getMeasuredHeight());
buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(getDrawingCache());
setDrawingCacheEnabled(false); // clear drawing cache
return b;
}
}

@ -19,14 +19,20 @@ package com.todoroo.astrid.helper;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.data.TagData;
import com.todoroo.astrid.data.Update;
/**
* <p>
@ -46,18 +52,19 @@ import com.todoroo.andlib.service.ContextManager;
*/
@SuppressWarnings("nls")
public class ImageDiskCache extends DiskCache<String, Bitmap> {
private static final String TAG = ImageDiskCache.class.getSimpleName();
private static final String TAG = ImageDiskCache.class.getSimpleName();
public static final String CACHED_IDENTIFIER = "cached::";
static final boolean DEBUG = false;
static final boolean DEBUG = false;
private long mIDCounter = 0;
private long mIDCounter = 0;
private static ImageDiskCache mInstance;
private static ImageDiskCache mInstance;
private final CompressFormat mCompressFormat;
private final int mQuality;
private final CompressFormat mCompressFormat;
private final int mQuality;
public static ImageDiskCache getInstance() {
if (mInstance == null) {
@ -66,109 +73,136 @@ public class ImageDiskCache extends DiskCache<String, Bitmap> {
return mInstance;
}
private ImageDiskCache(File file, CompressFormat format, int quality) {
super(file, null, getExtension(format));
public static ImageDiskCache getInstance(Context context) {
if (mInstance == null) {
mInstance = new ImageDiskCache(context.getCacheDir(), CompressFormat.JPEG, 85);
}
return mInstance;
}
private ImageDiskCache(File file, CompressFormat format, int quality) {
super(file, null, getExtension(format));
mCompressFormat = format;
mQuality = quality;
}
mCompressFormat = format;
mQuality = quality;
}
private static String getExtension(CompressFormat format) {
String extension;
switch (format) {
case JPEG:
extension = ".jpg";
break;
case PNG:
extension = ".png";
break;
default:
throw new IllegalArgumentException();
}
return extension;
}
/**
* If loading a number of images where you don't have a unique ID to
* represent the individual load, this can be used to generate a sequential
* ID.
*
* @return a new unique ID
*/
public synchronized long getNewID() {
return mIDCounter++;
}
@Override
protected Bitmap fromDisk(String key, InputStream in) {
if (DEBUG) {
Log.d(TAG, "disk cache hit");
}
try {
final Bitmap image = BitmapFactory.decodeStream(in);
return image;
} catch (final OutOfMemoryError oom) {
return null;
}
}
@Override
protected void toDisk(String key, Bitmap image, OutputStream out) {
if (DEBUG) {
Log.d(TAG, "cache write for key " + key);
}
if (image != null) {
if (!image.compress(mCompressFormat, mQuality, out)) {
Log.e(TAG, "error writing compressed image to disk for key "
+ key);
}
} else {
Log.e(TAG, "attempting to write null image to cache");
}
}
/**
* @param uri
* the image uri
* @return a key unique to the given uri
*/
public String getKey(Uri uri) {
return uri.toString();
}
/**
* Returns an opaque cache key representing the given uri, width and height.
*
* @param uri
* an image uri
* @param width
* the desired image max width
* @param height
* the desired image max height
* @return a cache key unique to the given parameters
*/
public String getKey(Uri uri, int width, int height) {
return uri.buildUpon()
.appendQueryParameter("width", String.valueOf(width))
.appendQueryParameter("height", String.valueOf(height)).build()
.toString();
}
/**
* Cancels all the asynchronous image loads.
* Note: currently does not function properly.
*
*/
public void cancelLoads() {
// TODO actually make it possible to cancel tasks
}
String extension;
switch (format) {
case JPEG:
extension = ".jpg";
break;
case PNG:
extension = ".png";
break;
default:
throw new IllegalArgumentException();
}
return extension;
}
/**
* If loading a number of images where you don't have a unique ID to
* represent the individual load, this can be used to generate a sequential
* ID.
*
* @return a new unique ID
*/
public synchronized long getNewID() {
return mIDCounter++;
}
@Override
protected Bitmap fromDisk(String key, InputStream in) {
if (DEBUG) {
Log.d(TAG, "disk cache hit");
}
try {
final Bitmap image = BitmapFactory.decodeStream(in);
return image;
} catch (final OutOfMemoryError oom) {
return null;
}
}
@Override
protected void toDisk(String key, Bitmap image, OutputStream out) {
if (DEBUG) {
Log.d(TAG, "cache write for key " + key);
}
if (image != null) {
if (!image.compress(mCompressFormat, mQuality, out)) {
Log.e(TAG, "error writing compressed image to disk for key "
+ key);
}
} else {
Log.e(TAG, "attempting to write null image to cache");
}
}
/**
* @param uri
* the image uri
* @return a key unique to the given uri
*/
public String getKey(Uri uri) {
return uri.toString();
}
/**
* Returns an opaque cache key representing the given uri, width and height.
*
* @param uri
* an image uri
* @param width
* the desired image max width
* @param height
* the desired image max height
* @return a cache key unique to the given parameters
*/
public String getKey(Uri uri, int width, int height) {
return uri.buildUpon()
.appendQueryParameter("width", String.valueOf(width))
.appendQueryParameter("height", String.valueOf(height)).build()
.toString();
}
/**
* Cancels all the asynchronous image loads.
* Note: currently does not function properly.
*
*/
public void cancelLoads() {
// TODO actually make it possible to cancel tasks
}
@Override
public boolean contains(String key) {
return !TextUtils.isEmpty(key) && key.startsWith(CACHED_IDENTIFIER) && super.contains(key);
}
public static String getPictureHash(Update update) {
return String.format("%s%s%s", CACHED_IDENTIFIER, update.getValue(Update.TASK), update.getValue(Update.CREATION_DATE));
}
public static String getPictureHash(TagData tagData) {
long tag_date = 0;
if (tagData.containsValue(TagData.CREATION_DATE)) {
tag_date = tagData.getValue(TagData.CREATION_DATE);
}
if (tag_date == 0) {
tag_date = DateUtilities.dateToUnixtime(new Date());
}
return String.format("%s%s%s", CACHED_IDENTIFIER,tagData.getValue(TagData.NAME), tag_date);
}
}

@ -1,7 +1,5 @@
package com.todoroo.astrid.ui;
import greendroid.widget.AsyncImageView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@ -25,6 +23,7 @@ import android.widget.TextView.OnEditorActionListener;
import com.timsu.astrid.R;
import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.actfm.sync.ActFmPreferenceService;
import com.todoroo.astrid.helper.AsyncImageView;
public class PeopleContainer extends LinearLayout {
@ -83,16 +82,35 @@ public class PeopleContainer extends LinearLayout {
textView.setHint(R.string.actfm_person_or_tag_hint);
}
final ImageButton removeButton = (ImageButton)tagItem.findViewById(R.id.button1);
removeButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
TextView lastView = getLastTextView();
if(lastView == textView && textView.getText().length() == 0)
return;
if(getChildCount() > 1)
removeView(tagItem);
else {
textView.setText(""); //$NON-NLS-1$
textView.setEnabled(true);
}
}
});
final AsyncImageView imageView = (AsyncImageView)tagItem.
findViewById(R.id.icon);
imageView.setUrl(image);
if (TextUtils.isEmpty(textView.getText())) {
imageView.setDefaultImageResource(R.drawable.icn_default_person_image);
imageView.setDefaultImageResource(R.drawable.icn_add_contact);
removeButton.setVisibility(View.GONE);
}
else {
imageView.setDefaultImageResource(R.drawable.icn_add_contact);
imageView.setDefaultImageResource(R.drawable.icn_default_person_image);
removeButton.setVisibility(View.VISIBLE);
}
textView.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
@ -108,10 +126,16 @@ public class PeopleContainer extends LinearLayout {
int count) {
if(count > 0 && getLastTextView() == textView) {
addPerson("", ""); //$NON-NLS-1$
imageView.setDefaultImageResource(R.drawable.icn_default_person_image);
}
else {
}
if (TextUtils.isEmpty(textView.getText())) {
imageView.setDefaultImageResource(R.drawable.icn_add_contact);
removeButton.setVisibility(View.GONE);
}
else {
imageView.setDefaultImageResource(R.drawable.icn_default_person_image);
removeButton.setVisibility(View.VISIBLE);
}
if(onAddNewPerson != null)
@ -131,22 +155,6 @@ public class PeopleContainer extends LinearLayout {
}
});
ImageButton removeButton = (ImageButton)tagItem.findViewById(R.id.button1);
removeButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
TextView lastView = getLastTextView();
if(lastView == textView && textView.getText().length() == 0)
return;
if(getChildCount() > 1)
removeView(tagItem);
else {
textView.setText(""); //$NON-NLS-1$
textView.setEnabled(true);
}
}
});
return textView;
}

@ -1,6 +1,6 @@
package com.todoroo.astrid.ui;
import greendroid.widget.AsyncImageView;
import com.todoroo.astrid.helper.AsyncImageView;
import java.io.IOException;
import java.io.StringReader;

Loading…
Cancel
Save