Modified provider to supply only folders with feeds with content. Modified count stacking for pos/neg/neutral. Added backgrounds.

This commit is contained in:
RyanBateman 2012-07-06 12:13:12 -04:00
parent 523d45236e
commit d6df6945de
17 changed files with 212 additions and 16 deletions

View file

@ -32,7 +32,8 @@
<activity
android:name=".activity.Profile"
android:label="@string/profile" />
android:label="@string/profile"
android:hardwareAccelerated="false" />
<service android:name=".service.SyncService" />

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" >
<solid android:color="@color/negative"/>
</shape>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" >
<solid android:color="@color/neutral" />
</shape>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" >
<solid android:color="@color/positive"/>
</shape>

View file

@ -17,14 +17,13 @@
android:layout_height="fill_parent"
android:gravity="center_vertical" >
<ImageView
<com.newsblur.view.RoundedImageView
android:id="@+id/profile_picture"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_margin="20dp"
android:background="@color/darkgray"
android:contentDescription="@string/description_profile_picture"
android:scaleType="center"
android:scaleType="fitCenter"
android:src="@drawable/person" />
</LinearLayout>

View file

@ -4,27 +4,69 @@
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical"
android:paddingTop="10dp"
android:paddingBottom="10dp" >
android:paddingBottom="10dp"
android:paddingTop="10dp" >
<TextView
android:id="@+id/row_feedname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="70dp"
android:ellipsize="end"
android:singleLine="true"
android:textColor="@color/black"
android:textSize="16dp"
android:layout_marginLeft="70dp"
android:textStyle="bold" />
<ImageView
android:id="@+id/row_feedfavicon"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_marginLeft="40dp"
android:layout_centerVertical="true"
android:layout_marginLeft="40dp"
android:contentDescription="@string/description_favicon" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:gravity="right"
android:orientation="horizontal" >
<TextView
android:id="@+id/row_feednegative"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginRight="10dp"
android:background="@drawable/negative_count_circle"
android:gravity="center"
android:textColor="@color/white"
android:textSize="10dp"
android:textStyle="bold" />
<TextView
android:id="@+id/row_feedneutral"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginRight="10dp"
android:background="@drawable/neutral_count_circle"
android:gravity="center"
android:textColor="@color/white"
android:textSize="10dp"
android:textStyle="bold" />
<TextView
android:id="@+id/row_feedpositive"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginRight="10dp"
android:background="@drawable/positive_count_circle"
android:gravity="center"
android:textColor="@color/white"
android:textSize="10dp"
android:textStyle="bold" />
</LinearLayout>
</RelativeLayout>

View file

@ -12,4 +12,10 @@
<color name="half_black">#7000</color>
<color name="transparent">#0000</color>
<color name="half_darkgray">#77434343</color>
<color name="positive">#3B7613</color>
<color name="neutral">#F6C000</color>
<color name="negative">#DE0000</color>
</resources>

View file

@ -6,6 +6,7 @@ import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.MenuItem;
import com.newsblur.R;
import com.newsblur.fragment.ProfileDetailsFragment;
@ -32,4 +33,16 @@ public class Profile extends SherlockFragmentActivity {
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}

View file

@ -28,6 +28,9 @@ public class BlurDatabase extends SQLiteOpenHelper {
DatabaseConstants.FEED_ACTIVE + TEXT + ", " +
DatabaseConstants.FEED_ADDRESS + TEXT + ", " +
DatabaseConstants.FEED_FAVICON_COLOUR + TEXT + ", " +
DatabaseConstants.FEED_POSITIVE_COUNT + INTEGER + ", " +
DatabaseConstants.FEED_NEGATIVE_COUNT + INTEGER + ", " +
DatabaseConstants.FEED_NEUTRAL_COUNT + INTEGER + ", " +
DatabaseConstants.FEED_FAVICON + TEXT + ", " +
DatabaseConstants.FEED_FAVICON_FADE + TEXT + ", " +
DatabaseConstants.FEED_LINK + TEXT + ", " +

View file

@ -19,6 +19,9 @@ public class DatabaseConstants {
public static final String FEED_FAVICON_COLOUR = "favicon_colour";
public static final String FEED_ACTIVE = "active";
public static final String FEED_FAVICON = "favicon";
public static final String FEED_POSITIVE_COUNT = "ps";
public static final String FEED_NEUTRAL_COUNT = "nt";
public static final String FEED_NEGATIVE_COUNT = "ng";
public static final String FEED_FOLDER_MAP_TABLE = "feed_folder_map";
public static final String FEED_FOLDER_FEED_ID = "feed_id";
@ -44,5 +47,6 @@ public class DatabaseConstants {
public static final String STORY_READ = "read";
public static final String STORY_FEED_ID = "feed_id";
}

View file

@ -126,11 +126,14 @@ public class FeedProvider extends ContentProvider {
cursor = db.rawQuery("SELECT * FROM " + DatabaseConstants.FEED_FOLDER_MAP_TABLE +
" INNER JOIN " + DatabaseConstants.FEED_TABLE +
" ON " + DatabaseConstants.FEED_TABLE + "." + DatabaseConstants.FEED_ID + " = " + DatabaseConstants.FEED_FOLDER_MAP_TABLE + "." + DatabaseConstants.FEED_FOLDER_FEED_ID +
" WHERE " + DatabaseConstants.FEED_FOLDER_MAP_TABLE + "." + DatabaseConstants.FEED_FOLDER_FOLDER_NAME + " = ? ", selectionArgs);
" WHERE " + DatabaseConstants.FEED_FOLDER_MAP_TABLE + "." + DatabaseConstants.FEED_FOLDER_FOLDER_NAME + " = ? AND " +
" (" + DatabaseConstants.FEED_NEGATIVE_COUNT + " + " + DatabaseConstants.FEED_NEUTRAL_COUNT + " + " + DatabaseConstants.FEED_POSITIVE_COUNT + ") " +
" ORDER BY " + DatabaseConstants.FEED_TABLE + "." + DatabaseConstants.FEED_TITLE + " ASC", selectionArgs);
break;
// Querying for all folders
case ALL_FOLDERS:
cursor = db.rawQuery("SELECT * FROM " + DatabaseConstants.FOLDER_TABLE, null);
cursor = db.rawQuery("SELECT * FROM " + DatabaseConstants.FOLDER_TABLE + " " +
"ORDER BY " + DatabaseConstants.FOLDER_NAME + " ASC", null);
break;
}
return cursor;

View file

@ -22,6 +22,15 @@ public class Feed {
@SerializedName("favicon")
public String favicon;
@SerializedName("nt")
public int neutralCount;
@SerializedName("ng")
public int negativeCount;
@SerializedName("ps")
public int positiveCount;
@SerializedName("favicon_fade")
public String faviconFade;
@ -43,6 +52,9 @@ public class Feed {
values.put(DatabaseConstants.FEED_ACTIVE, active);
values.put(DatabaseConstants.FEED_ADDRESS, address);
values.put(DatabaseConstants.FEED_FAVICON_COLOUR, faviconColour);
values.put(DatabaseConstants.FEED_POSITIVE_COUNT, positiveCount);
values.put(DatabaseConstants.FEED_NEUTRAL_COUNT, neutralCount);
values.put(DatabaseConstants.FEED_NEGATIVE_COUNT, negativeCount);
values.put(DatabaseConstants.FEED_FAVICON_FADE, faviconFade);
values.put(DatabaseConstants.FEED_FAVICON, favicon);
values.put(DatabaseConstants.FEED_LINK, feedLink);

View file

@ -30,8 +30,8 @@ public class FolderFeedListFragment extends Fragment {
final String[] groupFrom = new String[] { DatabaseConstants.FOLDER_NAME };
final int[] groupTo = new int[] { R.id.row_foldername };
final String[] childFrom = new String[] { DatabaseConstants.FEED_TITLE, DatabaseConstants.FEED_FAVICON };
final int[] childTo = new int[] { R.id.row_feedname, R.id.row_feedfavicon };
final String[] childFrom = new String[] { DatabaseConstants.FEED_TITLE, DatabaseConstants.FEED_FAVICON, DatabaseConstants.FEED_NEUTRAL_COUNT, DatabaseConstants.FEED_NEGATIVE_COUNT, DatabaseConstants.FEED_POSITIVE_COUNT };
final int[] childTo = new int[] { R.id.row_feedname, R.id.row_feedfavicon, R.id.row_feedneutral, R.id.row_feednegative, R.id.row_feedpositive };
folderAdapter = new FolderTreeAdapter(getActivity(), cursor, R.layout.row_folder_collapsed, R.layout.row_folder_expanded, groupFrom, groupTo, R.layout.row_feed, childFrom, childTo);
folderAdapter.setViewBinder(new FolderTreeViewBinder());

View file

@ -5,6 +5,7 @@ import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.newsblur.R;
@ -27,8 +28,10 @@ public class ProfileDetailsFragment extends Fragment {
TextView username = (TextView) v.findViewById(R.id.profile_username);
username.setText(user.username);
TextView bio = (TextView) v.findViewById(R.id.profile_bio);
bio.setText(user.bio);
TextView location = (TextView) v.findViewById(R.id.profile_location);
location.setText(user.location);
@ -44,6 +47,9 @@ public class ProfileDetailsFragment extends Fragment {
TextView subscriberCount = (TextView) v.findViewById(R.id.profile_subscribercount);
subscriberCount.setText("" + user.numberOfSubscribers);
final ImageView imageView = (ImageView) v.findViewById(R.id.profile_picture);
imageView.setImageBitmap(PrefsUtil.getUserImage(getActivity()));
return v;
}

View file

@ -1,21 +1,31 @@
package com.newsblur.util;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import com.newsblur.activity.PrefConstants;
import com.newsblur.domain.UserProfile;
public class PrefsUtil {
public static void saveCookie(final Context context, final String cookie) {
final SharedPreferences preferences = context.getSharedPreferences(PrefConstants.PREFERENCES, 0);
final Editor edit = preferences.edit();
edit.putString(PrefConstants.PREF_COOKIE, cookie);
edit.commit();
}
public static void saveUserDetails(final Context context, final UserProfile profile) {
final SharedPreferences preferences = context.getSharedPreferences(PrefConstants.PREFERENCES, 0);
final Editor edit = preferences.edit();
@ -36,11 +46,12 @@ public class PrefsUtil {
edit.putString(PrefConstants.USER_USERNAME, profile.username);
edit.putString(PrefConstants.USER_WEBSITE, profile.website);
edit.commit();
saveUserImage(context, profile.photoUrl);
}
public static UserProfile getUserDetails(final Context context) {
UserProfile user = new UserProfile();
final SharedPreferences preferences = context.getSharedPreferences(PrefConstants.PREFERENCES, 0);
user.averageStoriesPerMonth = preferences.getInt(PrefConstants.USER_AVERAGE_STORIES_PER_MONTH, 0);
user.bio = preferences.getString(PrefConstants.USER_BIO, null);
@ -58,7 +69,31 @@ public class PrefsUtil {
user.subscriptionCount = preferences.getInt(PrefConstants.USER_SUBSCRIBER_COUNT, 0);
user.username = preferences.getString(PrefConstants.USER_USERNAME, null);
user.website = preferences.getString(PrefConstants.USER_WEBSITE, null);
return user;
}
private static void saveUserImage(final Context context, String pictureUrl) {
Bitmap bitmap = null;
try {
URL url = new URL(pictureUrl);
URLConnection connection;
connection = url.openConnection();
connection.setUseCaches(true);
bitmap = BitmapFactory.decodeStream( (InputStream) connection.getContent());
File file = context.getCacheDir();
File imageFile = new File(file.getPath() + "/userProfilePicture");
bitmap.compress(CompressFormat.PNG, 100, new FileOutputStream(imageFile));
} catch (IOException e) {
e.printStackTrace();
}
}
public static Bitmap getUserImage(final Context context) {
return BitmapFactory.decodeFile(context.getCacheDir().getPath() + "/userProfilePicture");
}
}

View file

@ -8,6 +8,7 @@ import android.util.Base64;
import android.view.View;
import android.widget.ImageView;
import android.widget.SimpleCursorTreeAdapter.ViewBinder;
import android.widget.TextView;
import com.newsblur.database.DatabaseConstants;
@ -20,6 +21,33 @@ public class FolderTreeViewBinder implements ViewBinder {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
((ImageView) view).setImageBitmap(bitmap);
return true;
} else if (TextUtils.equals(cursor.getColumnName(columnIndex), DatabaseConstants.FEED_POSITIVE_COUNT)) {
int feedPositive = cursor.getInt(columnIndex);
if (feedPositive > 0) {
view.setVisibility(View.VISIBLE);
((TextView) view).setText("" + feedPositive);
} else {
view.setVisibility(View.GONE);
}
return true;
} else if (TextUtils.equals(cursor.getColumnName(columnIndex), DatabaseConstants.FEED_NEUTRAL_COUNT)) {
int feedNeutral = cursor.getInt(columnIndex);
if (feedNeutral > 0) {
view.setVisibility(View.VISIBLE);
((TextView) view).setText("" + feedNeutral);
} else {
view.setVisibility(View.GONE);
}
return true;
} else if (TextUtils.equals(cursor.getColumnName(columnIndex), DatabaseConstants.FEED_NEGATIVE_COUNT)) {
int feedNegative = cursor.getInt(columnIndex);
if (feedNegative > 0) {
view.setVisibility(View.VISIBLE);
((TextView) view).setText("" + feedNegative);
} else {
view.setVisibility(View.GONE);
}
return true;
}
return false;
}

View file

@ -0,0 +1,32 @@
package com.newsblur.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.widget.ImageView;
public class RoundedImageView extends ImageView {
private Path clipPath;
public RoundedImageView(Context context) {
super(context);
clipPath = new Path();
}
public RoundedImageView(Context context, AttributeSet attrs) {
super(context, attrs);
clipPath = new Path();
}
// TODO: Fix this to use proper anti-aliasing for the corners
protected void onDraw(Canvas canvas) {
clipPath.addRoundRect(new RectF(0, 0, getWidth(), getHeight()), getWidth() / 12, getWidth() / 12, Path.Direction.CW);
canvas.clipPath(clipPath);
super.onDraw(canvas);
};
}