mirror of
https://github.com/viq/NewsBlur.git
synced 2025-09-18 21:43:31 +00:00
flesh out grid view items
This commit is contained in:
parent
b5fa158dc7
commit
7d425df6f2
13 changed files with 295 additions and 103 deletions
17
clients/android/NewsBlur/res/drawable-nodpi/item_border.xml
Normal file
17
clients/android/NewsBlur/res/drawable-nodpi/item_border.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- on API 14 and 15, the default solid is a black square, not nothing. -->
|
||||
<solid android:color="@android:color/transparent" />
|
||||
<padding
|
||||
android:bottom="1dp"
|
||||
android:top="1dp"
|
||||
android:left="1dp"
|
||||
android:right="1dp"
|
||||
/>
|
||||
<stroke
|
||||
android:color="@color/gray55"
|
||||
android:width="1dp"
|
||||
android:height="1dp"
|
||||
/>
|
||||
<corners android:radius="0dp" />
|
||||
</shape>
|
|
@ -1,38 +1,122 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.newsblur.view.SquaredRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.newsblur.view.SquaredRelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:newsblur="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
newsblur:addedHeight="60"
|
||||
android:background="@drawable/item_border"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/story_item_thumbnail"
|
||||
android:layout_width="match_parent"
|
||||
<View
|
||||
android:id="@+id/story_item_favicon_borderbar_1"
|
||||
android:layout_width="4dp"
|
||||
android:layout_height="match_parent"
|
||||
/>
|
||||
|
||||
<View
|
||||
android:id="@+id/story_item_favicon_borderbar_2"
|
||||
android:layout_width="4dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="1dp"
|
||||
android:layout_marginBottom="1dp"
|
||||
android:layout_marginLeft="1dp"
|
||||
android:layout_marginRight="1dp"
|
||||
android:layout_toRightOf="@id/story_item_favicon_borderbar_1"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/story_item_date"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginBottom="2dp"
|
||||
android:layout_marginRight="4dp"
|
||||
android:singleLine="true"
|
||||
style="?storyDateText"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/story_item_feedicon"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="15dp"
|
||||
android:layout_toRightOf="@id/story_item_favicon_borderbar_2"
|
||||
android:layout_above="@id/story_item_date"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginLeft="18dp"
|
||||
android:layout_marginBottom="2dp"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/story_item_feedtitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_toRightOf="@id/story_item_feedicon"
|
||||
android:layout_above="@id/story_item_date"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:layout_marginRight="2dp"
|
||||
android:layout_marginBottom="2dp"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
style="?storyFeedTitleText"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/story_item_saved_icon"
|
||||
android:src="@drawable/clock"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_above="@id/story_item_feedtitle"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginTop="2dp"
|
||||
android:layout_marginLeft="2dp"
|
||||
android:layout_marginRight="2dp"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/story_item_shared_icon"
|
||||
android:src="@drawable/ic_shared"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_above="@id/story_item_feedtitle"
|
||||
android:layout_toLeftOf="@id/story_item_saved_icon"
|
||||
android:layout_alignWithParentIfMissing="true"
|
||||
android:layout_marginTop="2dp"
|
||||
android:layout_marginLeft="2dp"
|
||||
android:layout_marginRight="2dp"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/story_item_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/row_item_feedicon"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:paddingTop="4dp"
|
||||
android:layout_above="@id/story_item_feedtitle"
|
||||
android:layout_toLeftOf="@id/story_item_shared_icon"
|
||||
android:layout_marginLeft="26dp"
|
||||
android:layout_marginRight="2dp"
|
||||
android:layout_marginBottom="2dp"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/story_item_inteldot"
|
||||
android:layout_width="9dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignTop="@id/story_item_title"
|
||||
android:layout_alignBottom="@id/story_item_title"
|
||||
android:layout_toRightOf="@id/story_item_favicon_borderbar_2"
|
||||
android:layout_marginLeft="4dp"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/story_item_thumbnail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_above="@id/story_item_title"
|
||||
android:layout_marginBottom="2dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:scaleType="centerCrop"
|
||||
/>
|
||||
|
||||
</com.newsblur.view.SquaredRelativeLayout>
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<attr name="flow" format="string" />
|
||||
<attr name="imageViewSize" format="integer" />
|
||||
<attr name="selectorFolderBackground" format="string" />
|
||||
<attr name="selectorFeedBackground" format="string" />
|
||||
<attr name="feedRowNeutCountText" format="string" />
|
||||
|
@ -41,8 +39,15 @@
|
|||
<attr name="selectorOverlayBackgroundText" format="string" />
|
||||
<attr name="muteicon" format="string" />
|
||||
|
||||
<attr name="flow" format="string" />
|
||||
<attr name="imageViewSize" format="integer" />
|
||||
<declare-styleable name="FlowLayout">
|
||||
<attr name="flow" />
|
||||
<attr name="imageViewSize" />
|
||||
</declare-styleable>
|
||||
|
||||
<attr name="addedHeight" format="integer" />
|
||||
<declare-styleable name="SquaredRelativeLayout">
|
||||
<attr name="addedHeight" />
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
<color name="dark_story_background_selected">#4C4C4C</color>
|
||||
|
||||
<color name="story_feed_title_text">#606060</color>
|
||||
<color name="dark_story_feed_title_text">#F7F8F5</color>
|
||||
<color name="dark_story_feed_title_text">@color/gray55</color>
|
||||
<color name="story_date_text">#424242</color>
|
||||
<color name="dark_story_date_text">#BDBDBD</color>
|
||||
<color name="story_content_text">#404040</color>
|
||||
|
|
|
@ -265,32 +265,35 @@ public abstract class ItemsList extends NbActivity implements StoryOrderChangedL
|
|||
}
|
||||
fs.setSearchQuery(q);
|
||||
if (!TextUtils.equals(q, oldQuery)) {
|
||||
NBSyncService.resetReadingSession();
|
||||
FeedUtils.prepareReadingSession(fs);
|
||||
triggerSync();
|
||||
itemSetFragment.resetEmptyState();
|
||||
itemSetFragment.hasUpdated();
|
||||
itemSetFragment.scrollToTop();
|
||||
NBSyncService.resetReadingSession();
|
||||
NBSyncService.resetFetchState(fs);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storyOrderChanged(StoryOrder newValue) {
|
||||
updateStoryOrderPreference(newValue);
|
||||
itemSetFragment.resetEmptyState();
|
||||
itemSetFragment.hasUpdated();
|
||||
itemSetFragment.scrollToTop();
|
||||
NBSyncService.resetFetchState(fs);
|
||||
triggerSync();
|
||||
restartReadingSession();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFilterChanged(ReadFilter newValue) {
|
||||
updateReadFilterPreference(newValue);
|
||||
restartReadingSession();
|
||||
}
|
||||
|
||||
private void restartReadingSession() {
|
||||
NBSyncService.resetFetchState(fs);
|
||||
NBSyncService.resetReadingSession();
|
||||
FeedUtils.prepareReadingSession(fs);
|
||||
triggerSync();
|
||||
itemSetFragment.resetEmptyState();
|
||||
itemSetFragment.hasUpdated();
|
||||
itemSetFragment.scrollToTop();
|
||||
NBSyncService.resetFetchState(fs);
|
||||
triggerSync();
|
||||
}
|
||||
|
||||
// NB: this callback is for the text size slider
|
||||
|
|
|
@ -1125,6 +1125,7 @@ public class BlurDatabaseHelper {
|
|||
}
|
||||
|
||||
public void clearStorySession() {
|
||||
com.newsblur.util.Log.i(this, "reading session reset");
|
||||
synchronized (RW_MUTEX) {dbRW.delete(DatabaseConstants.READING_SESSION_TABLE, null, null);}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,9 @@ public class StoryViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
|||
public final static int VIEW_TYPE_STORY = 1;
|
||||
public final static int VIEW_TYPE_FOOTER = 2;
|
||||
|
||||
private final static float defaultTextSize_story_item_feedtitle = 13f;
|
||||
private final static float defaultTextSize_story_item_title = 14f;
|
||||
private final static float defaultTextSize_story_item_date = 12f;
|
||||
|
||||
private final static float READ_STORY_ALPHA = 0.4f;
|
||||
private final static int READ_STORY_ALPHA_B255 = (int) (255f * READ_STORY_ALPHA);
|
||||
|
@ -84,6 +86,10 @@ public class StoryViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
|||
setHasStableIds(true);
|
||||
}
|
||||
|
||||
public void updateFeedSet(FeedSet fs) {
|
||||
this.fs = fs;
|
||||
}
|
||||
|
||||
public synchronized void addFooterView(View v) {
|
||||
footerViews.add(v);
|
||||
}
|
||||
|
@ -93,7 +99,7 @@ public class StoryViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
|||
return (getStoryCount() + footerViews.size());
|
||||
}
|
||||
|
||||
private int getStoryCount() {
|
||||
public int getStoryCount() {
|
||||
if (showNone || (cursor == null)) {
|
||||
return 0;
|
||||
} else {
|
||||
|
@ -145,12 +151,30 @@ public class StoryViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
|||
this.textSize = textSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
|
||||
if (viewType == VIEW_TYPE_STORY) {
|
||||
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_story_tile, viewGroup, false);
|
||||
return new StoryViewHolder(v);
|
||||
} else {
|
||||
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_footer_tile, viewGroup, false);
|
||||
return new FooterViewHolder(v);
|
||||
}
|
||||
}
|
||||
|
||||
public class StoryViewHolder extends RecyclerView.ViewHolder
|
||||
implements View.OnClickListener, View.OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener {
|
||||
|
||||
@Bind(R.id.story_item_favicon_borderbar_1) View leftBarOne;
|
||||
@Bind(R.id.story_item_favicon_borderbar_2) View leftBarTwo;
|
||||
@Bind(R.id.story_item_inteldot) ImageView intelDot;
|
||||
@Bind(R.id.story_item_thumbnail) ImageView thumbView;
|
||||
@Bind(R.id.story_item_feedicon) ImageView feedIconView;
|
||||
@Bind(R.id.story_item_feedtitle) TextView feedTitleView;
|
||||
@Bind(R.id.story_item_title) TextView storyTitleView;
|
||||
@Bind(R.id.story_item_date) TextView storyDate;
|
||||
@Bind(R.id.story_item_saved_icon) View savedView;
|
||||
@Bind(R.id.story_item_shared_icon) View sharedView;
|
||||
|
||||
Story story;
|
||||
ImageLoader.PhotoToLoad thumbLoader;
|
||||
|
@ -170,7 +194,6 @@ public class StoryViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
|||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||
com.newsblur.util.Log.d(this, "INFLATE: " + story.storyHash);
|
||||
MenuInflater inflater = new MenuInflater(context);
|
||||
UIUtils.inflateStoryContextMenu(menu, inflater, context, fs, story);
|
||||
for (int i=0; i<menu.size(); i++) {
|
||||
|
@ -185,27 +208,6 @@ public class StoryViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
|||
}
|
||||
}
|
||||
|
||||
public class FooterViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
@Bind(R.id.footer_view_inner) FrameLayout innerView;
|
||||
|
||||
public FooterViewHolder(View view) {
|
||||
super(view);
|
||||
ButterKnife.bind(FooterViewHolder.this, view);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
|
||||
if (viewType == VIEW_TYPE_STORY) {
|
||||
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_story_tile, viewGroup, false);
|
||||
return new StoryViewHolder(v);
|
||||
} else {
|
||||
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_footer_tile, viewGroup, false);
|
||||
return new FooterViewHolder(v);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
|
||||
if (viewHolder instanceof StoryViewHolder) {
|
||||
|
@ -216,46 +218,60 @@ public class StoryViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
|||
|
||||
Story story = Story.fromCursor(cursor);
|
||||
vh.story = story;
|
||||
//com.newsblur.util.Log.d(this, "BINDING: " + story.storyHash);
|
||||
|
||||
// when first created, tiles' views tend to not yet have their dimensions calculated, but
|
||||
// upon being recycled they will often have a known size, which lets us give a max size to
|
||||
// the image loader, which in turn can massively optimise loading. the image loader will
|
||||
// reject nonsene values
|
||||
int thumbSizeGuess = vh.thumbView.getMeasuredHeight();
|
||||
|
||||
// there is a not-unlikely chance that the recycler will re-use a tile for a story with the
|
||||
// same thumbnail. only load it if it is different.
|
||||
if (!TextUtils.equals(story.thumbnailUrl, vh.lastThumbUrl)) {
|
||||
vh.lastThumbUrl = story.thumbnailUrl;
|
||||
// the view will display a stale, recycled thumb before the new one loads if the old is not cleared
|
||||
vh.thumbView.setImageDrawable(null);
|
||||
vh.lastThumbUrl = story.thumbnailUrl;
|
||||
vh.thumbLoader = FeedUtils.thumbnailLoader.displayImage(story.thumbnailUrl, vh.thumbView, 0, true, thumbSizeGuess);
|
||||
}
|
||||
vh.thumbLoader = FeedUtils.thumbnailLoader.displayImage(story.thumbnailUrl, vh.thumbView, 0, true, thumbSizeGuess);
|
||||
|
||||
String feedColor = cursor.getString(cursor.getColumnIndex(DatabaseConstants.FEED_FAVICON_COLOR));
|
||||
String feedFade = cursor.getString(cursor.getColumnIndex(DatabaseConstants.FEED_FAVICON_FADE));
|
||||
vh.leftBarOne.setBackgroundColor(UIUtils.decodeColourValue(feedColor, Color.GRAY));
|
||||
vh.leftBarTwo.setBackgroundColor(UIUtils.decodeColourValue(feedFade, Color.LTGRAY));
|
||||
|
||||
if (! ignoreIntel) {
|
||||
int score = cursor.getInt(cursor.getColumnIndex(DatabaseConstants.STORY_INTELLIGENCE_TOTAL));
|
||||
if (score > 0) {
|
||||
vh.intelDot.setImageResource(R.drawable.g_icn_focus);
|
||||
} else if (score == 0) {
|
||||
vh.intelDot.setImageResource(R.drawable.g_icn_unread);
|
||||
} else {
|
||||
vh.intelDot.setImageResource(R.drawable.g_icn_hidden);
|
||||
}
|
||||
} else {
|
||||
vh.intelDot.setImageResource(android.R.color.transparent);
|
||||
}
|
||||
|
||||
vh.storyTitleView.setText(UIUtils.fromHtml(story.title));
|
||||
vh.storyDate.setText(StoryUtils.formatShortDate(context, new Date(story.timestamp)));
|
||||
|
||||
// lists with mixed feeds get added info, but single feeds do not
|
||||
if (!singleFeed) {
|
||||
String faviconUrl = cursor.getString(cursor.getColumnIndex(DatabaseConstants.FEED_FAVICON_URL));
|
||||
FeedUtils.iconLoader.displayImage(faviconUrl, vh.feedIconView, 0, false);
|
||||
vh.feedTitleView.setText(cursor.getString(cursor.getColumnIndex(DatabaseConstants.FEED_TITLE)));
|
||||
vh.feedIconView.setVisibility(View.VISIBLE);
|
||||
vh.feedTitleView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
vh.feedIconView.setVisibility(View.GONE);
|
||||
vh.feedTitleView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
// dynamic text sizing
|
||||
vh.storyTitleView.setTextSize(textSize * defaultTextSize_story_item_title);
|
||||
|
||||
// read/unread fading
|
||||
if (this.ignoreReadStatus || (! story.read)) {
|
||||
vh.thumbView.setImageAlpha(255);
|
||||
vh.feedIconView.setImageAlpha(255);
|
||||
vh.storyTitleView.setAlpha(1.0f);
|
||||
vh.storyTitleView.setTypeface(null, Typeface.BOLD);
|
||||
if (vh.story.starred) {
|
||||
vh.savedView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
vh.thumbView.setImageAlpha(READ_STORY_ALPHA_B255);
|
||||
vh.feedIconView.setImageAlpha(READ_STORY_ALPHA_B255);
|
||||
vh.storyTitleView.setAlpha(READ_STORY_ALPHA);
|
||||
vh.storyTitleView.setTypeface(null, Typeface.NORMAL);
|
||||
vh.savedView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
/*
|
||||
boolean shared = false;
|
||||
findshareloop: for (String userId : story.sharedUserIds) {
|
||||
if (TextUtils.equals(userId, user.id)) {
|
||||
|
@ -263,7 +279,38 @@ public class StoryViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
|||
break findshareloop;
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (shared) {
|
||||
vh.sharedView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
vh.sharedView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
// dynamic text sizing
|
||||
vh.feedTitleView.setTextSize(textSize * defaultTextSize_story_item_feedtitle);
|
||||
vh.storyTitleView.setTextSize(textSize * defaultTextSize_story_item_title);
|
||||
vh.storyDate.setTextSize(textSize * defaultTextSize_story_item_date);
|
||||
|
||||
// read/unread fading
|
||||
if (this.ignoreReadStatus || (! story.read)) {
|
||||
vh.leftBarOne.getBackground().setAlpha(255);
|
||||
vh.leftBarTwo.getBackground().setAlpha(255);
|
||||
vh.intelDot.setImageAlpha(255);
|
||||
vh.thumbView.setImageAlpha(255);
|
||||
vh.feedIconView.setImageAlpha(255);
|
||||
vh.feedTitleView.setAlpha(1.0f);
|
||||
vh.storyTitleView.setAlpha(1.0f);
|
||||
vh.storyDate.setAlpha(1.0f);
|
||||
} else {
|
||||
vh.leftBarOne.getBackground().setAlpha(READ_STORY_ALPHA_B255);
|
||||
vh.leftBarTwo.getBackground().setAlpha(READ_STORY_ALPHA_B255);
|
||||
vh.intelDot.setImageAlpha(READ_STORY_ALPHA_B255);
|
||||
vh.thumbView.setImageAlpha(READ_STORY_ALPHA_B255);
|
||||
vh.feedIconView.setImageAlpha(READ_STORY_ALPHA_B255);
|
||||
vh.feedTitleView.setAlpha(READ_STORY_ALPHA);
|
||||
vh.storyTitleView.setAlpha(READ_STORY_ALPHA);
|
||||
vh.storyDate.setAlpha(READ_STORY_ALPHA);
|
||||
}
|
||||
|
||||
} else {
|
||||
FooterViewHolder vh = (FooterViewHolder) viewHolder;
|
||||
vh.innerView.removeAllViews();
|
||||
|
@ -275,6 +322,16 @@ public class StoryViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
|||
|
||||
}
|
||||
|
||||
public class FooterViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
@Bind(R.id.footer_view_inner) FrameLayout innerView;
|
||||
|
||||
public FooterViewHolder(View view) {
|
||||
super(view);
|
||||
ButterKnife.bind(FooterViewHolder.this, view);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewRecycled(RecyclerView.ViewHolder viewHolder) {
|
||||
if (viewHolder instanceof StoryViewHolder) {
|
||||
|
|
|
@ -167,7 +167,7 @@ public class ItemGridFragment extends ItemSetFragment {
|
|||
} else {
|
||||
topProgressView.setVisibility(View.INVISIBLE);
|
||||
bottomProgressView.setVisibility(View.INVISIBLE);
|
||||
if (cursorSeenYet && NBSyncService.isFeedSetExhausted(getFeedSet())) {
|
||||
if (cursorSeenYet && NBSyncService.isFeedSetExhausted(getFeedSet()) && (adapter.getStoryCount() > 0)) {
|
||||
fleuronFooter.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
@ -210,11 +210,11 @@ public class ItemGridFragment extends ItemSetFragment {
|
|||
int totalCount = layoutManager.getItemCount();
|
||||
int visibleCount = layoutManager.getChildCount();
|
||||
int lastVisible = layoutManager.findLastVisibleItemPosition();
|
||||
//com.newsblur.util.Log.d(this, String.format("SCROLL total:%d bound:%d last%d", totalCount, visibleCount, lastVisible));
|
||||
|
||||
// load an extra page or two worth of stories past the viewport
|
||||
int desiredStoryCount = lastVisible + (visibleCount*2) + 1;
|
||||
// load an extra page worth of stories past the viewport plus at least two rows to prime the height calc
|
||||
int desiredStoryCount = lastVisible + (visibleCount*2) + (GRID_COLUMN_COUNT*2);
|
||||
triggerRefresh(desiredStoryCount, totalCount);
|
||||
//com.newsblur.util.Log.d(this, String.format(" total:%d bound:%d last%d desire:%d", totalCount, visibleCount, lastVisible, desiredStoryCount));
|
||||
|
||||
// TODO: mark on scroll?
|
||||
}
|
||||
|
@ -233,6 +233,7 @@ public class ItemGridFragment extends ItemSetFragment {
|
|||
@Override
|
||||
protected void updateAdapter(Cursor cursor) {
|
||||
adapter.swapCursor(cursor);
|
||||
adapter.updateFeedSet(getFeedSet());
|
||||
adapter.notifyDataSetChanged();
|
||||
if (cursor.getCount() > 0) {
|
||||
emptyView.setVisibility(View.INVISIBLE);
|
||||
|
@ -245,10 +246,6 @@ public class ItemGridFragment extends ItemSetFragment {
|
|||
ensureSufficientStories();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void resetAdapter() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setShowNone(boolean showNone) {
|
||||
adapter.setShowNone(showNone);
|
||||
|
|
|
@ -247,11 +247,6 @@ public class ItemListFragment extends ItemSetFragment implements OnScrollListene
|
|||
adapter.swapCursor(cursor);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void resetAdapter() {
|
||||
//if (adapter != null) adapter.notifyDataSetInvalidated();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setShowNone(boolean showNone) {
|
||||
adapter.setShowNone(showNone);
|
||||
|
|
|
@ -84,9 +84,8 @@ public abstract class ItemSetFragment extends NbFragment implements LoaderManage
|
|||
* Indicate that the DB was cleared.
|
||||
*/
|
||||
public void resetEmptyState() {
|
||||
resetAdapter();
|
||||
setShowNone(true);
|
||||
cursorSeenYet = false;
|
||||
FeedUtils.dbHelper.clearStorySession();
|
||||
}
|
||||
|
||||
public abstract void setLoading(boolean isLoading);
|
||||
|
@ -162,13 +161,11 @@ public abstract class ItemSetFragment extends NbFragment implements LoaderManage
|
|||
|
||||
protected abstract void updateAdapter(Cursor cursor);
|
||||
|
||||
protected abstract void resetAdapter();
|
||||
|
||||
protected abstract void setShowNone(boolean showNone);
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<Cursor> loader) {
|
||||
resetAdapter();
|
||||
;
|
||||
}
|
||||
|
||||
public abstract void setTextSize(Float size);
|
||||
|
|
|
@ -118,6 +118,8 @@ public class NBSyncService extends Service {
|
|||
/** Feed to reset to zero-state, so it is fetched fresh, presumably with new filters. */
|
||||
private static FeedSet ResetFeed;
|
||||
|
||||
private static final Object MUTEX_ResetFeed = new Object();
|
||||
|
||||
/** Actions that may need to be double-checked locally due to overlapping API calls. */
|
||||
private static List<ReadingAction> FollowupActions;
|
||||
static { FollowupActions = new ArrayList<ReadingAction>(); }
|
||||
|
@ -657,21 +659,24 @@ public class NBSyncService extends Service {
|
|||
FeedSet fs = PendingFeed;
|
||||
|
||||
try {
|
||||
// see if we need to quickly reset fetch state for a feed. we
|
||||
// do this before the loop to prevent-mid loop state corruption
|
||||
synchronized (MUTEX_ResetFeed) {
|
||||
if (ResetFeed != null) {
|
||||
com.newsblur.util.Log.i(this.getClass().getName(), "Resetting state for feed set: " + ResetFeed);
|
||||
ExhaustedFeeds.remove(ResetFeed);
|
||||
FeedStoriesSeen.remove(ResetFeed);
|
||||
FeedPagesSeen.remove(ResetFeed);
|
||||
ResetFeed = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (fs == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
prepareReadingSession(dbHelper, fs);
|
||||
|
||||
// see if we need to quickly reset fetch state for a feed. we
|
||||
// do this before the loop to prevent-mid loop state corruption
|
||||
if (ResetFeed != null) {
|
||||
ExhaustedFeeds.remove(ResetFeed);
|
||||
FeedStoriesSeen.remove(ResetFeed);
|
||||
FeedPagesSeen.remove(ResetFeed);
|
||||
ResetFeed = null;
|
||||
}
|
||||
|
||||
LastFeedSet = fs;
|
||||
|
||||
if (ExhaustedFeeds.contains(fs)) {
|
||||
|
@ -1040,7 +1045,7 @@ public class NBSyncService extends Service {
|
|||
PendingFeed = fs;
|
||||
PendingFeedTarget = desiredStoryCount;
|
||||
|
||||
if (AppConstants.VERBOSE_LOG) Log.d(NBSyncService.class.getName(), "callerhas: " + callerSeen + " have:" + alreadySeen + " want:" + desiredStoryCount + " pending:" + alreadyPending);
|
||||
//if (AppConstants.VERBOSE_LOG) Log.d(NBSyncService.class.getName(), "callerhas: " + callerSeen + " have:" + alreadySeen + " want:" + desiredStoryCount + " pending:" + alreadyPending);
|
||||
|
||||
if (!fs.equals(LastFeedSet)) {
|
||||
return true;
|
||||
|
@ -1095,8 +1100,10 @@ public class NBSyncService extends Service {
|
|||
* Reset the API pagniation state for the given feedset, presumably because the order or filter changed.
|
||||
*/
|
||||
public static void resetFetchState(FeedSet fs) {
|
||||
com.newsblur.util.Log.d(NBSyncService.class.getName(), "requesting feed fetch state reset");
|
||||
ResetFeed = fs;
|
||||
synchronized (MUTEX_ResetFeed) {
|
||||
com.newsblur.util.Log.d(NBSyncService.class.getName(), "requesting feed fetch state reset");
|
||||
ResetFeed = fs;
|
||||
}
|
||||
}
|
||||
|
||||
public static void addRecountCandidates(FeedSet fs) {
|
||||
|
|
|
@ -24,6 +24,7 @@ import android.util.Log;
|
|||
import android.util.TypedValue;
|
||||
import android.text.Html;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.MenuInflater;
|
||||
|
@ -528,4 +529,16 @@ public class UIUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static int decodeColourValue(String val, int defaultVal) {
|
||||
int result = defaultVal;
|
||||
if (val == null) return result;
|
||||
if (TextUtils.equals(val, "null")) return result;
|
||||
try {
|
||||
result = Color.parseColor("#" + val);
|
||||
} catch (NumberFormatException nfe) {
|
||||
com.newsblur.util.Log.e(UIUtils.class.getName(), "feed supplied bad color info: " + nfe.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,29 +1,45 @@
|
|||
package com.newsblur.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.newsblur.R;
|
||||
import com.newsblur.util.UIUtils;
|
||||
|
||||
public class SquaredRelativeLayout extends RelativeLayout {
|
||||
|
||||
private int addedHeightPx;
|
||||
|
||||
public SquaredRelativeLayout(Context context) {
|
||||
super(context);
|
||||
addedHeightPx = 0;
|
||||
}
|
||||
|
||||
public SquaredRelativeLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
bindAttrs(context, attrs);
|
||||
}
|
||||
|
||||
public SquaredRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
bindAttrs(context, attrs);
|
||||
}
|
||||
|
||||
private void bindAttrs(Context context, AttributeSet attrs) {
|
||||
TypedArray styledAttributes = context.obtainStyledAttributes(attrs, R.styleable.SquaredRelativeLayout);
|
||||
int addedHeightAttributeDp = styledAttributes.getInt(R.styleable.SquaredRelativeLayout_addedHeight, 0);
|
||||
addedHeightPx = UIUtils.dp2px(context, addedHeightAttributeDp);
|
||||
styledAttributes.recycle();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
if (heightMeasureSpec > widthMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec + addedHeightPx);
|
||||
} else {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec + addedHeightPx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue