Got the details. but the linear layout messes me up

pull/14/head
Tim Su 16 years ago
parent a0451dbab0
commit d1dc887920

@ -1,71 +1,72 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- See the file "LICENSE" for the full license governing this code. --> <!-- See the file "LICENSE" for the full license governing this code. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@android:drawable/list_selector_background" android:background="@android:drawable/list_selector_background"
android:orientation="vertical"> android:paddingTop="4dip"
android:paddingBottom="4dip"
android:paddingLeft="4dip"
android:paddingRight="6dip">
<LinearLayout <RelativeLayout android:id="@+id/main"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingLeft="4dip" android:layout_alignParentTop="true"
android:paddingRight="6dip" android:layout_alignParentLeft="true"
android:paddingTop="4dip" android:minHeight="48dip">
android:paddingBottom="4dip"
android:minHeight="48dip"
android:orientation="horizontal">
<!-- completion check-box --> <!-- completion check-box -->
<CheckBox android:id="@+id/completeBox" <CheckBox android:id="@+id/completeBox"
android:layout_width="34dip" android:layout_width="34dip"
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:layout_weight="1" android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:paddingLeft="5dip" android:paddingLeft="5dip"
android:button="@drawable/btn_check"/> android:button="@drawable/btn_check"/>
<LinearLayout android:id="@+id/details" <!-- task name -->
<TextView android:id="@+id/title"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="100" android:layout_alignParentTop="true"
android:minHeight="38dip" android:layout_toRightOf="@id/completeBox"
android:paddingLeft="40dip" android:paddingLeft="10dip"
android:paddingRight="6dip" style="@style/TextAppearance.TAd_ItemTitle"
android:orientation="vertical"> android:gravity="center_vertical"/>
<!-- task name --> <!-- due date -->
<TextView android:id="@+id/title" <TextView android:id="@+id/dueDate"
android:layout_width="fill_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="22sp" android:layout_below="@id/title"
style="@style/TextAppearance.TAd_ItemTitle" android:layout_toRightOf="@id/completeBox"
android:gravity="center_vertical"/> android:paddingLeft="10dip"
android:singleLine="true"/>
<!-- due date -->
<TextView android:id="@+id/dueDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"/>
<!-- other details go here -->
</LinearLayout> </RelativeLayout>
<!-- importance --> <TextView android:id="@+id/details"
<View android:id="@+id/importance" android:layout_width="fill_parent"
android:layout_width="2dip" android:layout_height="wrap_content"
android:layout_height="fill_parent"/> android:layout_below="@id/main"
android:layout_alignParentLeft="true" />
</LinearLayout>
<LinearLayout android:id="@+id/actions" <LinearLayout android:id="@+id/actions"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/details"
android:layout_alignParentLeft="true"
android:background="#4499bbcc" android:background="#4499bbcc"
android:visibility="gone" android:visibility="gone"
android:paddingTop="4dip" android:paddingTop="4dip"
android:paddingLeft="6dip"
android:paddingRight="6dip"
android:orientation="horizontal" /> android:orientation="horizontal" />
</LinearLayout> <!-- importance -->
<View android:id="@+id/importance"
android:layout_width="2dip"
android:layout_height="fill_parent"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true" />
</RelativeLayout>

@ -49,11 +49,12 @@
</style> </style>
<style name="TextAppearance.TAd_ItemDetails"> <style name="TextAppearance.TAd_ItemDetails">
<item name="android:textSize">14sp</item> <item name="android:textSize">10sp</item>
<item name="android:textColor">#ff777777</item> <item name="android:textColor">#ff777777</item>
</style> </style>
<style name="TextAppearance.TAd_ItemDueDate" parent="TextAppearance.TAd_ItemDetails"> <style name="TextAppearance.TAd_ItemDueDate" parent="TextAppearance.TAd_ItemDetails">
<item name="android:textSize">14sp</item>
<item name="android:textColor">#ff7777aa</item> <item name="android:textColor">#ff7777aa</item>
</style> </style>

@ -2,6 +2,8 @@ package com.todoroo.astrid.adapter;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
@ -10,6 +12,7 @@ import android.content.res.Resources;
import android.database.Cursor; import android.database.Cursor;
import android.graphics.Paint; import android.graphics.Paint;
import android.text.Html; import android.text.Html;
import android.util.Log;
import android.view.ContextMenu; import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo; import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -98,7 +101,9 @@ public class TaskAdapter extends CursorAdapter {
private final int resource; private final int resource;
private final LayoutInflater inflater; private final LayoutInflater inflater;
protected OnCompletedTaskListener onCompletedTaskListener = null; protected OnCompletedTaskListener onCompletedTaskListener = null;
private final int fontSize; private int fontSize;
private final HashMap<Long, LinkedHashSet<TaskDetail>> detailCache =
new HashMap<Long, LinkedHashSet<TaskDetail>>();
/** /**
* Constructor * Constructor
@ -147,7 +152,7 @@ public class TaskAdapter extends CursorAdapter {
viewHolder.nameView = (TextView)view.findViewById(R.id.title); viewHolder.nameView = (TextView)view.findViewById(R.id.title);
viewHolder.completeBox = (CheckBox)view.findViewById(R.id.completeBox); viewHolder.completeBox = (CheckBox)view.findViewById(R.id.completeBox);
viewHolder.dueDate = (TextView)view.findViewById(R.id.dueDate); viewHolder.dueDate = (TextView)view.findViewById(R.id.dueDate);
viewHolder.details = (LinearLayout)view.findViewById(R.id.details); viewHolder.details = (TextView)view.findViewById(R.id.details);
viewHolder.actions = (LinearLayout)view.findViewById(R.id.actions); viewHolder.actions = (LinearLayout)view.findViewById(R.id.actions);
viewHolder.importance = (View)view.findViewById(R.id.importance); viewHolder.importance = (View)view.findViewById(R.id.importance);
@ -169,11 +174,12 @@ public class TaskAdapter extends CursorAdapter {
@Override @Override
public void bindView(View view, Context context, Cursor c) { public void bindView(View view, Context context, Cursor c) {
TodorooCursor<Task> cursor = (TodorooCursor<Task>)c; TodorooCursor<Task> cursor = (TodorooCursor<Task>)c;
Task actionItem = ((ViewHolder)view.getTag()).task; ViewHolder viewHolder = ((ViewHolder)view.getTag());
Task actionItem = viewHolder.task;
actionItem.readFromCursor(cursor); actionItem.readFromCursor(cursor);
setFieldContentsAndVisibility(view); setFieldContentsAndVisibility(view);
setTaskAppearance(view, actionItem.isCompleted()); setTaskAppearance(viewHolder, actionItem.isCompleted());
} }
/** Helper method to set the visibility based on if there's stuff inside */ /** Helper method to set the visibility based on if there's stuff inside */
@ -190,12 +196,12 @@ public class TaskAdapter extends CursorAdapter {
* @author Tim Su <tim@todoroo.com> * @author Tim Su <tim@todoroo.com>
* *
*/ */
public static class ViewHolder { public class ViewHolder {
public Task task; public Task task;
public TextView nameView; public TextView nameView;
public CheckBox completeBox; public CheckBox completeBox;
public TextView dueDate; public TextView dueDate;
public LinearLayout details; public TextView details;
public View importance; public View importance;
public LinearLayout actions; public LinearLayout actions;
public boolean expanded; public boolean expanded;
@ -218,14 +224,6 @@ public class TaskAdapter extends CursorAdapter {
nameView.setText(nameValue); nameView.setText(nameValue);
} }
// complete box
final CheckBox completeBox = viewHolder.completeBox; {
// show item as completed if it was recently checked
if(completedItems.containsKey(task.getId()))
task.setValue(Task.COMPLETION_DATE, DateUtilities.now());
completeBox.setChecked(task.isCompleted());
}
// due date / completion date // due date / completion date
final TextView dueDateView = viewHolder.dueDate; { final TextView dueDateView = viewHolder.dueDate; {
if(!task.isCompleted() && task.hasDueDate()) { if(!task.isCompleted() && task.hasDueDate()) {
@ -257,54 +255,112 @@ public class TaskAdapter extends CursorAdapter {
} }
} }
// other information - send out a request for it (only if not fling) // complete box
final LinearLayout detailsView = viewHolder.details; final CheckBox completeBox = viewHolder.completeBox; {
// show item as completed if it was recently checked
if(completedItems.containsKey(task.getId()))
task.setValue(Task.COMPLETION_DATE, DateUtilities.now());
completeBox.setChecked(task.isCompleted());
completeBox.getLayoutParams().height = dueDateView.getHeight() +
nameView.getHeight();
}
// task details - send out a request for it (only if not fling)
if(!isFling) { if(!isFling) {
detailsView.removeViews(2, detailsView.getChildCount() - 2); retrieveDetails(viewHolder);
retrieveDetails(detailsView, task.getId());
} }
// importance bar - must be set at end when view height is determined // importance bar - must be set at end when view height is determined
final View importanceView = viewHolder.importance; { final View importanceView = viewHolder.importance; {
int value = task.getValue(Task.IMPORTANCE); int value = task.getValue(Task.IMPORTANCE);
importanceView.setBackgroundColor(IMPORTANCE_COLORS[value]); importanceView.setBackgroundColor(IMPORTANCE_COLORS[value]);
importanceView.getLayoutParams().height =
((View)viewHolder.completeBox.getParent()).getHeight();
} }
} }
/** // --- task details
* Retrieve task details
*/ @SuppressWarnings("nls")
private void retrieveDetails(final LinearLayout view, final long taskId) { private void retrieveDetails(final ViewHolder viewHolder) {
// read internal details directly final long taskId = viewHolder.task.getId();
// check the cache
boolean inCache = false;
final LinkedHashSet<TaskDetail> details;
synchronized(detailCache) {
if(detailCache.containsKey(taskId))
inCache = true;
else
detailCache.put(taskId, new LinkedHashSet<TaskDetail>());
details = detailCache.get(taskId);
}
if(inCache) {
Log.e("detail-load-" + Thread.currentThread().getId(), "Already In Cache: " + taskId);
viewHolder.details.setVisibility(details.size() > 0 ? View.VISIBLE : View.GONE);
if(details.size() == 0)
return;
StringBuilder detailText = new StringBuilder();
for(Iterator<TaskDetail> iterator = details.iterator(); iterator.hasNext(); ) {
detailText.append(iterator.next().text);
if(iterator.hasNext())
detailText.append(" | ");
}
spanifyAndAdd(viewHolder.details, detailText.toString());
return;
}
Log.e("detail-load-" + Thread.currentThread().getId(), "Loading details: " + taskId);
// request details
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_REQUEST_DETAILS);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId);
activity.sendOrderedBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
// load internal details
new Thread() { new Thread() {
@Override @Override
public void run() { public void run() {
for(DetailExposer exposer : EXPOSERS) { for(DetailExposer exposer : EXPOSERS) {
if(Thread.interrupted())
return;
final TaskDetail detail = exposer.getTaskDetails(activity, taskId); final TaskDetail detail = exposer.getTaskDetails(activity, taskId);
if(detail == null) if(detail == null || details.contains(detail))
continue; continue;
ViewHolder holder = (ViewHolder)view.getTag();
if(holder == null || holder.task.getId() != taskId) CharSequence oldText = viewHolder.details.getText();
continue; if(oldText.length() > 0)
activity.runOnUiThread(new Runnable() { spanifyAndAdd(viewHolder.details, oldText + " | " + detail.text);
public void run() { else
view.addView(detailToView(detail)); spanifyAndAdd(viewHolder.details, detail.text);
}; details.add(detail);
});
} }
} Log.e("detail-load-" + Thread.currentThread().getId(), "Finished loading details: " + taskId);
};
}.start(); }.start();
}
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_REQUEST_DETAILS); @SuppressWarnings("nls")
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId); private void spanifyAndAdd(TextView details, String string) {
activity.sendOrderedBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); if(string.contains("<"))
details.setText(Html.fromHtml(string.trim().replace("\n", "<br>")));
else
details.setText(string.trim());
} }
/** /**
* Called to tell the cache to be cleared * Called to tell the cache to be cleared
*/ */
public void flushDetailCache() { public void flushDetailCache() {
// detailCache.clear();
}
@Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
fontSize = Preferences.getIntegerFromString(R.string.p_fontSize);
} }
/** /**
@ -312,8 +368,13 @@ public class TaskAdapter extends CursorAdapter {
* *
* @param taskId * @param taskId
*/ */
@SuppressWarnings("unused")
public synchronized void addDetails(ListView list, long taskId, TaskDetail detail) { public synchronized void addDetails(ListView list, long taskId, TaskDetail detail) {
if(detail == null) /*if(detail == null)
return;
LinkedHashSet<TaskDetail> details = detailCache.get(taskId);
if(details.contains(detail))
return; return;
// update view if it is visible // update view if it is visible
@ -322,36 +383,21 @@ public class TaskAdapter extends CursorAdapter {
ViewHolder viewHolder = (ViewHolder) list.getChildAt(i).getTag(); ViewHolder viewHolder = (ViewHolder) list.getChildAt(i).getTag();
if(viewHolder == null || viewHolder.task.getId() != taskId) if(viewHolder == null || viewHolder.task.getId() != taskId)
continue; continue;
details.add(detail);
TextView newView = detailToView(detail); TextView newView = detailToView(detail);
viewHolder.details.addView(newView); viewHolder.details.addView(newView);
break; break;
} }*/
}
/**
* Create a new view for the given detail
*
* @param detail
*/
@SuppressWarnings("nls")
private TextView detailToView(TaskDetail detail) {
TextView textView = new TextView(activity);
textView.setTextAppearance(activity, R.style.TextAppearance_TAd_ItemDetails);
textView.setText(Html.fromHtml(detail.text.replace("\n", "<br>")));
if(detail.color != 0)
textView.setTextColor(detail.color);
return textView;
} }
private final View.OnClickListener completeBoxListener = new View.OnClickListener() { private final View.OnClickListener completeBoxListener = new View.OnClickListener() {
public void onClick(View v) { public void onClick(View v) {
View container = (View) v.getParent(); ViewHolder viewHolder = (ViewHolder)((View)v.getParent().getParent()).getTag();
Task task = ((ViewHolder)container.getTag()).task; Task task = viewHolder.task;
completeTask(task, ((CheckBox)v).isChecked()); completeTask(task, ((CheckBox)v).isChecked());
// set check box to actual action item state // set check box to actual action item state
setTaskAppearance(container, task.isCompleted()); setTaskAppearance(viewHolder, task.isCompleted());
} }
}; };
@ -427,12 +473,10 @@ public class TaskAdapter extends CursorAdapter {
* @param name * @param name
* @param progress * @param progress
*/ */
void setTaskAppearance(View container, boolean state) { void setTaskAppearance(ViewHolder viewHolder, boolean state) {
CheckBox completed = (CheckBox)container.findViewById(R.id.completeBox); viewHolder.completeBox.setChecked(state);
TextView name = (TextView)container.findViewById(R.id.title);
completed.setChecked(state);
TextView name = viewHolder.nameView;
if(state) { if(state) {
name.setPaintFlags(name.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); name.setPaintFlags(name.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
name.setTextAppearance(activity, R.style.TextAppearance_TAd_ItemTitle_Completed); name.setTextAppearance(activity, R.style.TextAppearance_TAd_ItemTitle_Completed);

Loading…
Cancel
Save