Fixed bug whereby returning to the item list after viewing items would causing a network refresh based on old unread-items count.

This commit is contained in:
RyanBateman 2012-08-12 09:47:09 -04:00
parent e78d0bcaf2
commit eeab669e79
16 changed files with 232 additions and 200 deletions

View file

@ -1,6 +1,7 @@
body {
font-size: 2.0em;
padding: 5%;
background-color: #f5f5f5;
}
img {

View file

@ -8,7 +8,7 @@
android:id="@+id/itemlistfragment_list"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="@drawable/list_background"
android:background="@color/item_background"
android:divider="@drawable/divider_light"
android:dividerHeight="2dp" />

View file

@ -7,79 +7,80 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="9dp" >
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/list_background"
android:padding="10dp" >
android:orientation="horizontal" >
<TextView
android:id="@+id/reading_item_title"
<View
android:id="@+id/row_item_favicon_borderbar_1"
android:layout_width="8dp"
android:layout_height="match_parent" />
<View
android:id="@+id/row_item_favicon_borderbar_2"
android:layout_width="8dp"
android:layout_height="match_parent" />
<View
android:id="@+id/row_item_sidebar"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginLeft="-8dp"
android:layout_marginTop="12dp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="5dp"
android:shadowColor="@color/darkgray"
android:shadowDx="0"
android:shadowDy="0"
android:shadowRadius="15"
android:textColor="@color/white"
android:textSize="18dp"
android:textStyle="bold" />
<TextView
android:id="@+id/reading_item_authors"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@id/reading_item_title"
android:gravity="center_vertical|right"
android:minWidth="80dp"
android:textColor="@color/lightgray"
android:textSize="11dp" />
<TextView
android:id="@+id/reading_item_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@id/reading_item_title"
android:layout_marginBottom="5dp"
android:layout_marginRight="10dp"
android:textColor="@color/lightgray"
android:textSize="11dp"
android:textStyle="italic" />
<android.support.v7.widget.GridLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/reading_item_tags"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/reading_item_date"
android:layout_marginTop="5dp"
android:visibility="invisible" />
</RelativeLayout>
android:layout_height="wrap_content"
android:padding="8dp"
android:layout_marginBottom="8dp">
<TextView
android:id="@+id/reading_item_authors"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:maxLines="1"
android:minWidth="80dp"
android:textColor="@color/darkgray"
android:textSize="11dp" />
<TextView
android:id="@+id/reading_item_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginBottom="5dp"
android:layout_marginRight="10dp"
android:textColor="@color/darkgray"
android:textSize="11dp" />
<TextView
android:id="@+id/reading_item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/reading_item_date"
android:maxLines="2"
android:layout_marginRight="10dp"
android:textColor="@color/darkgray"
android:textSize="18dp" />
</RelativeLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/darkgray" />
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="@color/lightgray" />
android:layout_height="3dp"
android:background="@drawable/divider_light" />
<WebView
android:id="@+id/reading_webview"
android:layout_width="match_parent"
android:background="@color/item_background"
android:layout_height="wrap_content"
android:background="@color/item_background"
android:scrollbars="none" />
<RelativeLayout

View file

@ -7,7 +7,7 @@
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent" >
android:layout_height="match_parent">
<View
android:id="@+id/row_item_favicon_borderbar_1"
@ -54,8 +54,9 @@
android:id="@+id/row_item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/row_item_author"
android:layout_below="@id/row_item_author"
android:layout_toRightOf="@id/row_item_sidebar"
android:layout_marginLeft="8dp"
android:layout_below="@id/row_item_date"
android:layout_marginRight="8dp"
android:paddingTop="8dp"
android:paddingBottom="12dp"

View file

@ -1,6 +1,7 @@
package com.newsblur.activity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
@ -23,7 +24,9 @@ public class FeedItemsList extends ItemsList {
feedId = getIntent().getStringExtra(EXTRA_FEED);
final Uri feedUri = FeedProvider.FEEDS_URI.buildUpon().appendPath(feedId).build();
Feed feed = Feed.fromCursor(getContentResolver().query(feedUri, null, FeedProvider.getSelectionFromState(currentState), null, null));
Cursor cursor = getContentResolver().query(feedUri, null, FeedProvider.getSelectionFromState(currentState), null, null);
cursor.moveToFirst();
Feed feed = Feed.fromCursor(cursor);
setTitle(feed.title);
itemListFragment = (FeedItemListFragment) fragmentManager.findFragmentByTag(FeedItemListFragment.FRAGMENT_TAG);

View file

@ -9,6 +9,7 @@ import android.net.Uri;
import android.os.Bundle;
import com.newsblur.database.FeedProvider;
import com.newsblur.database.FeedReadingAdapter;
import com.newsblur.database.MarkStoryAsReadIntenallyTask;
import com.newsblur.domain.Feed;
import com.newsblur.domain.Story;
@ -29,11 +30,16 @@ public class FeedReading extends Reading {
stories = contentResolver.query(storiesURI, null, FeedProvider.getSelectionFromState(currentState), null, null);
final Uri feedUri = FeedProvider.FEEDS_URI.buildUpon().appendPath(feedId).build();
Feed feed = Feed.fromCursor(contentResolver.query(feedUri, null, null, null, null));
Cursor feedCursor = contentResolver.query(feedUri, null, null, null, null);
feedCursor.moveToFirst();
Feed feed = Feed.fromCursor(feedCursor);
setTitle(feed.title);
setupPager(stories);
readingAdapter = new FeedReadingAdapter(getSupportFragmentManager(), feed, stories);
setupPager();
createFloatingHeader(feed);
Story story = readingAdapter.getStory(passedPosition);
storiesToMarkAsRead.add(readingAdapter.getStory(passedPosition).id);

View file

@ -44,7 +44,7 @@ public abstract class Reading extends SherlockFragmentActivity implements OnPage
private ViewPager pager;
private FragmentManager fragmentManager;
protected FeedReadingAdapter readingAdapter;
protected ReadingAdapter readingAdapter;
protected ContentResolver contentResolver;
protected SyncUpdateFragment syncFragment;
@ -65,9 +65,8 @@ public abstract class Reading extends SherlockFragmentActivity implements OnPage
setResult(RESULT_OK);
}
protected void setupPager(Cursor stories) {
readingAdapter = new FeedReadingAdapter(fragmentManager, this, stories);
protected void setupPager() {
syncFragment = (SyncUpdateFragment) fragmentManager.findFragmentByTag(SyncUpdateFragment.TAG);
if (syncFragment == null) {
syncFragment = new SyncUpdateFragment();
@ -82,25 +81,6 @@ public abstract class Reading extends SherlockFragmentActivity implements OnPage
pager.setAdapter(readingAdapter);
pager.setCurrentItem(passedPosition);
}
protected void createFloatingHeader(final Feed feed) {
View view = findViewById(R.id.reading_floatbar);
GradientDrawable gradient;
int borderColor = Color.BLACK;
if (!TextUtils.equals(feed.faviconColour, "#null") && !TextUtils.equals(feed.faviconFade, "#null")) {
gradient = new GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, new int[] { Color.parseColor(feed.faviconColour), Color.parseColor(feed.faviconFade)});
borderColor = Color.parseColor(feed.faviconBorder);
} else {
gradient = new GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, new int[] { Color.DKGRAY, Color.LTGRAY });
}
Drawable[] layers = new Drawable[2];
layers[0] = gradient;
layers[1] = getResources().getDrawable(R.drawable.shiny_plastic);
view.setBackgroundDrawable(new LayerDrawable(layers));
findViewById(R.id.reading_divider).setBackgroundColor(borderColor);
findViewById(R.id.reading_divider_bottom).setBackgroundColor(borderColor);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {

View file

@ -0,0 +1,63 @@
package com.newsblur.activity;
import android.content.Context;
import android.database.Cursor;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.util.Log;
import android.view.ViewGroup;
import com.newsblur.domain.Story;
import com.newsblur.fragment.LoadingFragment;
public abstract class ReadingAdapter extends FragmentStatePagerAdapter {
protected Cursor stories;
private String TAG = "ReadingAdapter";
protected LoadingFragment loadingFragment;
public ReadingAdapter(FragmentManager fm, Cursor stories) {
super(fm);
this.stories = stories;
}
@Override
public abstract Fragment getItem(int position);
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
}
@Override
public int getCount() {
if (stories != null && stories.getCount() > 0) {
return stories.getCount();
} else {
Log.d(TAG , "No cursor - use loading view.");
return 1;
}
}
public Story getStory(int position) {
if (stories == null || position > stories.getCount()) {
return null;
} else {
stories.moveToPosition(position);
return Story.fromCursor(stories);
}
}
@Override
public int getItemPosition(Object object) {
if (object instanceof LoadingFragment) {
return POSITION_NONE;
} else {
return POSITION_UNCHANGED;
}
}
}

View file

@ -1,7 +1,6 @@
package com.newsblur.activity;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;

View file

@ -10,6 +10,7 @@ import android.os.Bundle;
import com.newsblur.database.FeedProvider;
import com.newsblur.database.MarkStoryAsReadIntenallyTask;
import com.newsblur.database.SocialFeedReadingAdapter;
import com.newsblur.domain.Story;
import com.newsblur.network.MarkSocialStoryAsReadTask;
@ -28,7 +29,10 @@ public class SocialFeedReading extends Reading {
Uri storiesURI = FeedProvider.SOCIALFEED_STORIES_URI.buildUpon().appendPath(userId).build();
stories = contentResolver.query(storiesURI, null, FeedProvider.getSelectionFromState(currentState), null, null);
setTitle(getIntent().getStringExtra(EXTRA_USERNAME));
setupPager(stories);
readingAdapter = new SocialFeedReadingAdapter(getSupportFragmentManager(), stories);
setupPager();
Story story = readingAdapter.getStory(passedPosition);
markSocialAsReadList.add(story.feedId, story.id);

View file

@ -1,72 +1,35 @@
package com.newsblur.database;
import android.content.Context;
import android.database.Cursor;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.util.Log;
import android.view.ViewGroup;
import com.newsblur.activity.ReadingAdapter;
import com.newsblur.domain.Feed;
import com.newsblur.domain.Story;
import com.newsblur.fragment.LoadingFragment;
import com.newsblur.fragment.ReadingItemFragment;
public class FeedReadingAdapter extends FragmentStatePagerAdapter {
public class FeedReadingAdapter extends ReadingAdapter {
private Cursor cursor;
private String TAG = "ReadingAdapter";
private LoadingFragment loadingFragment;
private final Feed feed;
public FeedReadingAdapter(final FragmentManager fragmentManager, final Context context, final Cursor cursor) {
super(fragmentManager);
this.cursor = cursor;
public FeedReadingAdapter(FragmentManager fm, Feed feed, Cursor stories) {
super(fm, stories);
this.feed = feed;
}
@Override
public Fragment getItem(int position) {
if (cursor == null || cursor.getCount() == 0) {
public Fragment getItem(int position) {
if (stories == null || stories.getCount() == 0) {
loadingFragment = new LoadingFragment();
return loadingFragment;
} else {
cursor.moveToPosition(position);
return ReadingItemFragment.newInstance(Story.fromCursor(cursor));
stories.moveToPosition(position);
return ReadingItemFragment.newInstance(Story.fromCursor(stories), feed.faviconColour, feed.faviconFade);
}
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
}
@Override
public int getCount() {
if (cursor != null && cursor.getCount() > 0) {
return cursor.getCount();
} else {
Log.d(TAG , "No cursor - use loading view.");
return 1;
}
}
public Story getStory(int position) {
if (cursor == null || position > cursor.getCount()) {
return null;
} else {
cursor.moveToPosition(position);
return Story.fromCursor(cursor);
}
}
@Override
public int getItemPosition(Object object) {
if (object instanceof LoadingFragment) {
return POSITION_NONE;
} else {
return POSITION_UNCHANGED;
}
}
}

View file

@ -1,62 +1,34 @@
package com.newsblur.database;
import android.content.Context;
import android.database.Cursor;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.util.Log;
import android.view.ViewGroup;
import com.newsblur.activity.ReadingAdapter;
import com.newsblur.domain.Story;
import com.newsblur.fragment.LoadingFragment;
import com.newsblur.fragment.ReadingItemFragment;
public class SocialFeedReadingAdapter extends FragmentStatePagerAdapter {
public class SocialFeedReadingAdapter extends ReadingAdapter {
private Cursor cursor;
private String TAG = "ReadingAdapter";
private String TAG = "FeedReadingAdapter";
private LoadingFragment loadingFragment;
public SocialFeedReadingAdapter(final FragmentManager fragmentManager, final Context context, final Cursor cursor) {
super(fragmentManager);
this.cursor = cursor;
public SocialFeedReadingAdapter(final FragmentManager fragmentManager, final Cursor cursor) {
super(fragmentManager, cursor);
}
@Override
public Fragment getItem(int position) {
if (cursor == null || cursor.getCount() == 0) {
public Fragment getItem(int position) {
if (stories == null || stories.getCount() == 0) {
loadingFragment = new LoadingFragment();
return loadingFragment;
} else {
cursor.moveToPosition(position);
return ReadingItemFragment.newInstance(Story.fromCursor(cursor));
stories.moveToPosition(position);
String feedFaviconColor = stories.getString(stories.getColumnIndex(DatabaseConstants.FEED_FAVICON_COLOUR));
String feedFaviconFade = stories.getString(stories.getColumnIndex(DatabaseConstants.FEED_FAVICON_FADE));
return ReadingItemFragment.newInstance(Story.fromCursor(stories), feedFaviconColor, feedFaviconFade);
}
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
}
@Override
public int getCount() {
if (cursor != null && cursor.getCount() > 0) {
return cursor.getCount();
} else {
Log.d(TAG , "No cursor - use loading view.");
return 1;
}
}
@Override
public int getItemPosition(Object object) {
if (object instanceof LoadingFragment) {
return POSITION_NONE;
} else {
return POSITION_UNCHANGED;
}
}
}

View file

@ -75,7 +75,6 @@ public class Feed {
public static Feed fromCursor(Cursor childCursor) {
Feed feed = new Feed();
childCursor.moveToFirst();
feed.active = Boolean.parseBoolean(childCursor.getString(childCursor.getColumnIndex(DatabaseConstants.FEED_ACTIVE)));
feed.address = childCursor.getString(childCursor.getColumnIndex(DatabaseConstants.FEED_ADDRESS));
feed.favicon = childCursor.getString(childCursor.getColumnIndex(DatabaseConstants.FEED_FAVICON));

View file

@ -112,7 +112,7 @@ public class Story implements Serializable {
return story;
}
private class Intelligence implements Serializable {
public class Intelligence implements Serializable {
private static final long serialVersionUID = -1314486209455376730L;
@SerializedName("feed")

View file

@ -48,6 +48,7 @@ public class FeedItemListFragment extends ItemListFragment implements LoaderMana
public static int ITEMLIST_LOADER = 0x01;
private int READING_RETURNED = 0x02;
private Feed feed;
private Cursor feedCursor;
public FeedItemListFragment(final String feedId, final int currentState) {
this.feedId = feedId;
@ -77,10 +78,9 @@ public class FeedItemListFragment extends ItemListFragment implements LoaderMana
contentResolver = getActivity().getContentResolver();
storiesUri = FeedProvider.FEED_STORIES_URI.buildUpon().appendPath(feedId).build();
Uri feedUri = FeedProvider.FEEDS_URI.buildUpon().appendPath(feedId).build();
Cursor cursor = contentResolver.query(storiesUri, null, FeedProvider.getSelectionFromState(currentState), null, DatabaseConstants.STORY_DATE + " DESC");
feed = Feed.fromCursor(contentResolver.query(feedUri, null, null, null, null));
setupFeed();
String[] groupFrom = new String[] { DatabaseConstants.STORY_TITLE, DatabaseConstants.STORY_AUTHORS, DatabaseConstants.STORY_READ, DatabaseConstants.STORY_SHORTDATE, DatabaseConstants.STORY_INTELLIGENCE_AUTHORS };
int[] groupTo = new int[] { R.id.row_item_title, R.id.row_item_author, R.id.row_item_title, R.id.row_item_date, R.id.row_item_sidebar };
@ -98,6 +98,13 @@ public class FeedItemListFragment extends ItemListFragment implements LoaderMana
return v;
}
private void setupFeed() {
Uri feedUri = FeedProvider.FEEDS_URI.buildUpon().appendPath(feedId).build();
feedCursor = contentResolver.query(feedUri, null, null, null, null);
feedCursor.moveToFirst();
feed = Feed.fromCursor(feedCursor);
}
@Override
public Loader<Cursor> onCreateLoader(int loaderId, Bundle bundle) {
Uri uri = FeedProvider.FEED_STORIES_URI.buildUpon().appendPath(feedId).build();
@ -113,6 +120,7 @@ public class FeedItemListFragment extends ItemListFragment implements LoaderMana
}
public void hasUpdated() {
setupFeed();
getLoaderManager().restartLoader(ITEMLIST_LOADER , null, this);
requestedPage = false;
}

View file

@ -6,10 +6,12 @@ import java.util.List;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.GridLayout;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@ -23,6 +25,7 @@ import android.widget.TextView;
import com.newsblur.R;
import com.newsblur.activity.NewsBlurApplication;
import com.newsblur.activity.Profile;
import com.newsblur.database.DatabaseConstants;
import com.newsblur.database.FeedProvider;
import com.newsblur.domain.Comment;
import com.newsblur.domain.Story;
@ -39,12 +42,15 @@ public class ReadingItemFragment extends Fragment {
private LayoutInflater inflater;
private APIManager apiManager;
private ImageLoader imageLoader;
private String feedColor;
private String feedFade;
public static ReadingItemFragment newInstance(Story story) {
public static ReadingItemFragment newInstance(Story story, String feedFaviconColor, String feedFaviconFade) {
ReadingItemFragment readingFragment = new ReadingItemFragment();
Bundle args = new Bundle();
args.putSerializable("story", story);
args.putString("feedColor", feedFaviconColor);
args.putString("feedFade", feedFaviconFade);
readingFragment.setArguments(args);
return readingFragment;
@ -57,12 +63,16 @@ public class ReadingItemFragment extends Fragment {
imageLoader = ((NewsBlurApplication) getActivity().getApplicationContext()).getImageLoader();
apiManager = new APIManager(getActivity());
story = getArguments() != null ? (Story) getArguments().getSerializable("story") : null;
feedColor = getArguments().getString("feedColor");
feedFade = getArguments().getString("feedFade");
}
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
this.inflater = inflater;
View view = inflater.inflate(R.layout.fragment_readingitem, null);
WebView web = (WebView) view.findViewById(R.id.reading_webview);
setupWebview(web);
setupItemMetadata(view);
@ -141,20 +151,42 @@ public class ReadingItemFragment extends Fragment {
private void setupItemMetadata(View view) {
View borderOne = view.findViewById(R.id.row_item_favicon_borderbar_1);
View borderTwo = view.findViewById(R.id.row_item_favicon_borderbar_2);
if (!TextUtils.equals(feedColor, "#null") && !TextUtils.equals(feedFade, "#null")) {
borderOne.setBackgroundColor(Color.parseColor(feedColor));
borderTwo.setBackgroundColor(Color.parseColor(feedFade));
} else {
borderOne.setBackgroundColor(Color.GRAY);
borderTwo.setBackgroundColor(Color.LTGRAY);
}
View sidebar = view.findViewById(R.id.row_item_sidebar);
int storyIntelligence = story.intelligence.intelligenceAuthors + story.intelligence.intelligenceTags + story.intelligence.intelligenceFeed + story.intelligence.intelligenceTitle;
if (storyIntelligence > 0) {
sidebar.setBackgroundResource(R.drawable.positive_count_circle);
} else if (storyIntelligence == 0) {
sidebar.setBackgroundResource(R.drawable.neutral_count_circle);
} else {
sidebar.setBackgroundResource(R.drawable.negative_count_circle);
}
TextView itemTitle = (TextView) view.findViewById(R.id.reading_item_title);
TextView itemDate = (TextView) view.findViewById(R.id.reading_item_date);
TextView itemAuthors = (TextView) view.findViewById(R.id.reading_item_authors);
GridLayout tagContainer = (GridLayout) view.findViewById(R.id.reading_item_tags);
if (story.tags != null || story.tags.length > 0) {
tagContainer.setVisibility(View.VISIBLE);
for (String tag : story.tags) {
View v = inflater.inflate(R.layout.tag_view, null);
TextView tagText = (TextView) v.findViewById(R.id.tag_text);
tagText.setText(tag);
tagContainer.addView(v);
}
}
// GridLayout tagContainer = (GridLayout) view.findViewById(R.id.reading_item_tags);
//
// if (story.tags != null || story.tags.length > 0) {
// tagContainer.setVisibility(View.VISIBLE);
// for (String tag : story.tags) {
// View v = inflater.inflate(R.layout.tag_view, null);
// TextView tagText = (TextView) v.findViewById(R.id.tag_text);
// tagText.setText(tag);
// tagContainer.addView(v);
// }
// }
itemDate.setText(story.shortDate);
itemTitle.setText(story.title);