Save subscribed subreddits and users to the SQLite database by using Room Persistence Library. Add a following section in the navigation drawer to display all the followed users. Add a NestedScrollView in the navigation drawer to wrap all the elements. Disable nested scrolling feature in all the RecyclerViews in the navigation drawer.

This commit is contained in:
Alex Ning 2018-07-29 20:25:55 +08:00
parent e3653eb503
commit ddc7b36e72
24 changed files with 665 additions and 160 deletions

View File

@ -28,10 +28,10 @@ repositories {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:28.0.0-alpha3'
implementation 'com.android.support:design:28.0.0-alpha3'
implementation 'com.android.support:appcompat-v7:28.0.0-beta01'
implementation 'com.android.support:design:28.0.0-beta01'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'com.android.support:support-v4:28.0.0-alpha3'
implementation 'com.android.support:support-v4:28.0.0-beta01'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
@ -39,10 +39,17 @@ dependencies {
implementation 'de.hdodenhof:circleimageview:2.2.0'
implementation 'com.google.android.exoplayer:exoplayer:2.7.0'
implementation 'com.google.android.exoplayer:exoplayer-dash:2.7.0'
implementation 'com.android.support:customtabs:28.0.0-alpha3'
implementation 'com.android.support:customtabs:28.0.0-beta01'
implementation 'com.alexvasilkov:gesture-views:2.5.2'
implementation 'com.android.support:cardview-v7:28.0.0-alpha3'
implementation 'com.android.support:cardview-v7:28.0.0-beta01'
implementation 'com.github.bumptech.glide:glide:4.6.1'
implementation 'com.github.pwittchen:swipe-rx2:0.3.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1'
// Room components
implementation "android.arch.persistence.room:runtime:$rootProject.roomVersion"
annotationProcessor "android.arch.persistence.room:compiler:$rootProject.roomVersion"
androidTestImplementation "android.arch.persistence.room:testing:$rootProject.roomVersion"
// Lifecycle components
implementation "android.arch.lifecycle:extensions:$rootProject.archLifecycleVersion"
annotationProcessor "android.arch.lifecycle:compiler:$rootProject.archLifecycleVersion"
}

View File

@ -64,7 +64,7 @@ class AcquireAccessToken {
public void onErrorResponse(VolleyError error) {
Toast.makeText(mContext, "Error getting the new access token", Toast.LENGTH_SHORT).show();
mAcquireAccessTokenListener.onAcquireAccessTokenFail();
Log.i("error get access token", error.getMessage());
Log.i("Error", "getting access token");
}
}) {
@Override

View File

@ -2,7 +2,6 @@ package ml.docilealligator.infinityforreddit;
import android.content.Context;
import android.net.Uri;
import android.util.Log;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
@ -14,23 +13,27 @@ import com.android.volley.toolbox.StringRequest;
import java.util.ArrayList;
import java.util.Map;
class FetchSubscribedSubreddits {
class FetchSubscribedThing {
interface FetchSubscribedSubredditsListener {
void onFetchSubscribedSubredditsSuccess(ArrayList<SubredditData> subredditData);
void onFetchSubscribedSubredditsSuccess(ArrayList<SubscribedSubredditData> subscribedSubredditData,
ArrayList<SubscribedUserData> subscribedUserData);
void onFetchSubscribedSubredditsFail();
}
private Context context;
private RequestQueue requestQueue;
private FetchSubscribedSubredditsListener mFetchSubscribedSubredditsListener;
private ArrayList<SubredditData> mSubredditData;
private ArrayList<SubscribedSubredditData> mSubscribedSubredditData;
private ArrayList<SubscribedUserData> mSubscribedUserData;
private String mLastItem;
FetchSubscribedSubreddits(Context context, RequestQueue requestQueue, ArrayList<SubredditData> subredditData) {
FetchSubscribedThing(Context context, RequestQueue requestQueue, ArrayList<SubscribedSubredditData> subscribedSubredditData,
ArrayList<SubscribedUserData> subscribedUserData) {
this.context = context;
this.requestQueue = requestQueue;
mSubredditData = subredditData;
mSubscribedSubredditData = subscribedSubredditData;
mSubscribedUserData = subscribedUserData;
}
void fetchSubscribedSubreddits(FetchSubscribedSubredditsListener fetchUserInfoListener, final int refreshTime) {
@ -47,15 +50,20 @@ class FetchSubscribedSubreddits {
StringRequest commentRequest = new StringRequest(Request.Method.GET, uri.toString(), new Response.Listener<String>() {
@Override
public void onResponse(String response) {
new ParseSubscribedSubreddits().parseSubscribedSubreddits(response, mSubredditData,
new ParseSubscribedSubreddits.ParseSubscribedSubredditsListener() {
new ParseSubscribedThing().parseSubscribedSubreddits(response, mSubscribedSubredditData,
mSubscribedUserData,
new ParseSubscribedThing.ParseSubscribedSubredditsListener() {
@Override
public void onParseSubscribedSubredditsSuccess(ArrayList<SubredditData> subredditData, String lastItem) {
mSubredditData = subredditData;
public void onParseSubscribedSubredditsSuccess(ArrayList<SubscribedSubredditData> subscribedSubredditData,
ArrayList<SubscribedUserData> subscribedUserData,
String lastItem) {
mSubscribedSubredditData = subscribedSubredditData;
mSubscribedUserData = subscribedUserData;
mLastItem = lastItem;
Log.i("last item", lastItem);
if(mLastItem.equals("null")) {
mFetchSubscribedSubredditsListener.onFetchSubscribedSubredditsSuccess(mSubredditData);
mFetchSubscribedSubredditsListener.onFetchSubscribedSubredditsSuccess(mSubscribedSubredditData,
mSubscribedUserData);
} else {
fetchSubscribedSubreddits(mFetchSubscribedSubredditsListener, refreshTime);
}

View File

@ -57,4 +57,7 @@ class JSONUtils {
static final String LINK_KARMA_KEY = "link_karma";
static final String COMMENT_KARMA_KEY = "comment_karma";
static final String DISPLAY_NAME = "display_name";
static final String SUBREDDIT_TYPE_KEY = "subreddit_type";
static final String SUBREDDIT_TYPE_VALUE_USER = "user";
}

View File

@ -2,10 +2,14 @@ package ml.docilealligator.infinityforreddit;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
@ -22,8 +26,7 @@ import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import de.hdodenhof.circleimageview.CircleImageView;
@ -38,7 +41,6 @@ public class MainActivity extends AppCompatActivity {
private TextView mKarmaTextView;
private CircleImageView mProfileImageView;
private ImageView mBannerImageView;
private RecyclerView mSubscribedSubredditRecyclerView;
private Fragment mFragment;
private RequestManager glide;
@ -49,7 +51,8 @@ public class MainActivity extends AppCompatActivity {
private String mKarma;
private boolean mFetchUserInfoSuccess;
private ArrayList<SubredditData> mSubredditData;
private SubscribedSubredditViewModel mSubscribedSubredditViewModel;
private SubscribedUserViewModel mSubscribedUserViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -70,8 +73,15 @@ public class MainActivity extends AppCompatActivity {
mProfileImageView = header.findViewById(R.id.profile_image_view_nav_header_main);
mBannerImageView = header.findViewById(R.id.banner_image_view_nav_header_main);
mSubscribedSubredditRecyclerView = findViewById(R.id.subscribed_subreddit_recycler_view_main_activity);
mSubscribedSubredditRecyclerView.setLayoutManager(new LinearLayoutManager(this));
RecyclerView subscribedSubredditRecyclerView = findViewById(R.id.subscribed_subreddit_recycler_view_main_activity);
subscribedSubredditRecyclerView.setLayoutManager(new LinearLayoutManager(this));
subscribedSubredditRecyclerView.setNestedScrollingEnabled(false);
final TextView subscriptionsLabelTextView = findViewById(R.id.subscriptions_label_main_activity);
RecyclerView subscribedUserRecyclerView = findViewById(R.id.subscribed_user_recycler_view_main_activity);
subscribedUserRecyclerView.setLayoutManager(new LinearLayoutManager(this));
subscribedUserRecyclerView.setNestedScrollingEnabled(false);
final TextView followingLabelTextView = findViewById(R.id.following_label_main_activity);
mName = getSharedPreferences(SharedPreferencesUtils.USER_INFO_FILE_KEY, Context.MODE_PRIVATE).getString(SharedPreferencesUtils.USER_KEY, "");
mProfileImageUrl = getSharedPreferences(SharedPreferencesUtils.USER_INFO_FILE_KEY, Context.MODE_PRIVATE).getString(SharedPreferencesUtils.PROFILE_IMAGE_URL_KEY, "");
@ -147,19 +157,55 @@ public class MainActivity extends AppCompatActivity {
}
}, 1);
}
new FetchSubscribedSubreddits(this, Volley.newRequestQueue(this), new ArrayList<SubredditData>())
.fetchSubscribedSubreddits(new FetchSubscribedSubreddits.FetchSubscribedSubredditsListener() {
final SubscribedSubredditRecyclerViewAdapter subredditadapter = new SubscribedSubredditRecyclerViewAdapter(this);
subscribedSubredditRecyclerView.setAdapter(subredditadapter);
mSubscribedSubredditViewModel = ViewModelProviders.of(this).get(SubscribedSubredditViewModel.class);
mSubscribedSubredditViewModel.getAllSubscribedSubreddits().observe(this, new Observer<List<SubscribedSubredditData>>() {
@Override
public void onChanged(@Nullable final List<SubscribedSubredditData> subscribedSubredditData) {
// Update the cached copy of the words in the adapter.
if(subscribedSubredditData == null || subscribedSubredditData.size() == 0) {
subscriptionsLabelTextView.setVisibility(View.GONE);
} else {
subscriptionsLabelTextView.setVisibility(View.VISIBLE);
}
subredditadapter.setSubscribedSubreddits(subscribedSubredditData);
}
});
final SubscribedUserRecyclerViewAdapter userAdapter = new SubscribedUserRecyclerViewAdapter(this);
subscribedUserRecyclerView.setAdapter(userAdapter);
mSubscribedUserViewModel = ViewModelProviders.of(this).get(SubscribedUserViewModel.class);
mSubscribedUserViewModel.getAllSubscribedUsers().observe(this, new Observer<List<SubscribedUserData>>() {
@Override
public void onChanged(@Nullable final List<SubscribedUserData> subscribedUserData) {
// Update the cached copy of the words in the adapter.
if(subscribedUserData == null || subscribedUserData.size() == 0) {
followingLabelTextView.setVisibility(View.GONE);
} else {
followingLabelTextView.setVisibility(View.VISIBLE);
}
userAdapter.setSubscribedUsers(subscribedUserData);
}
});
new FetchSubscribedThing(this, Volley.newRequestQueue(this), new ArrayList<SubscribedSubredditData>(),
new ArrayList<SubscribedUserData>())
.fetchSubscribedSubreddits(new FetchSubscribedThing.FetchSubscribedSubredditsListener() {
@Override
public void onFetchSubscribedSubredditsSuccess(ArrayList<SubredditData> subredditData) {
Collections.sort(subredditData, new Comparator<SubredditData>() {
@Override
public int compare(SubredditData subredditData, SubredditData t1) {
return subredditData.getName().toLowerCase().compareTo(t1.getName().toLowerCase());
}
});
mSubredditData = subredditData;
mSubscribedSubredditRecyclerView.setAdapter(new SubscribedSubredditRecyclerViewAdapter(
MainActivity.this, mSubredditData));
public void onFetchSubscribedSubredditsSuccess(ArrayList<SubscribedSubredditData> subscribedSubredditData,
ArrayList<SubscribedUserData> subscribedUserData) {
new InsertSubscribedThingsAsyncTask(
SubscribedSubredditRoomDatabase.getDatabase(MainActivity.this),
SubscribedUserRoomDatabase.getDatabase(MainActivity.this),
subscribedSubredditData,
subscribedUserData).execute();
/*new InsertSubscribedUsersAsyncTask(
SubscribedUserRoomDatabase.getDatabase(MainActivity.this),
subscribedUserData).execute();*/
}
@Override
@ -207,4 +253,52 @@ public class MainActivity extends AppCompatActivity {
glide.load(mBannerImageUrl).into(mBannerImageView);
}
}
private static class InsertSubscribedThingsAsyncTask extends AsyncTask<Void, Void, Void> {
private final SubscribedSubredditDao mSubredditDao;
private final SubscribedUserDao mUserDao;
private List<SubscribedSubredditData> subscribedSubredditData;
private List<SubscribedUserData> subscribedUserData;
InsertSubscribedThingsAsyncTask(SubscribedSubredditRoomDatabase subredditDb,
SubscribedUserRoomDatabase userDb,
List<SubscribedSubredditData> subscribedSubredditData,
List<SubscribedUserData> subscribedUserData) {
mSubredditDao = subredditDb.subscribedSubredditDao();
mUserDao = userDb.subscribedUserDao();
this.subscribedSubredditData = subscribedSubredditData;
this.subscribedUserData = subscribedUserData;
}
@Override
protected Void doInBackground(final Void... params) {
for(SubscribedSubredditData s : subscribedSubredditData) {
mSubredditDao.insert(s);
}
for(SubscribedUserData s : subscribedUserData) {
mUserDao.insert(s);
}
return null;
}
}
/*private static class InsertSubscribedUsersAsyncTask extends AsyncTask<Void, Void, Void> {
private final SubscribedUserDao mDao;
private List<SubscribedUserData> subscribedUserData;
InsertSubscribedUsersAsyncTask(SubscribedUserRoomDatabase db, List<SubscribedUserData> subscribedUserData) {
mDao = db.subscribedUserDao();
this.subscribedUserData = subscribedUserData;
}
@Override
protected Void doInBackground(final Void... params) {
for(SubscribedUserData s : subscribedUserData) {
mDao.insert(s);
}
return null;
}
}*/
}

View File

@ -152,7 +152,7 @@ class ParseBestPost {
videoPostData.setDownloadableGifOrVideo(false);
bestPostData.add(videoPostData);
} else {
} else if(data.has(JSONUtils.PREVIEW_KEY)){
JSONObject variations = data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0);
if (variations.has(JSONUtils.VARIANTS_KEY) && variations.getJSONObject(JSONUtils.VARIANTS_KEY).has(JSONUtils.MP4_KEY)) {
//Gif video post (MP4)
@ -194,6 +194,19 @@ class ParseBestPost {
bestPostData.add(linkPostData);
}
}
} else {
if (url.endsWith("jpg") || url.endsWith("png")) {
//Image post
Log.i("CP no preview image", Integer.toString(i));
int postType = BestPostData.IMAGE_TYPE;
bestPostData.add(new BestPostData(id, fullName, subredditName, formattedPostTime, title, url, url, permalink, score, postType, voteType, nsfw));
} else {
//Link post
Log.i("CP no preview link", Integer.toString(i));
int postType = BestPostData.LINK_TYPE;
BestPostData linkPostData = new BestPostData(id, fullName, subredditName, formattedPostTime, title, previewUrl, url, permalink, score, postType, voteType, nsfw);
bestPostData.add(linkPostData);
}
}
}
}

View File

@ -9,33 +9,41 @@ import org.json.JSONObject;
import java.util.ArrayList;
class ParseSubscribedSubreddits {
class ParseSubscribedThing {
interface ParseSubscribedSubredditsListener {
void onParseSubscribedSubredditsSuccess(ArrayList<SubredditData> subredditData, String lastItem);
void onParseSubscribedSubredditsSuccess(ArrayList<SubscribedSubredditData> subscribedSubredditData,
ArrayList<SubscribedUserData> subscribedUserData,
String lastItem);
void onParseSubscribedSubredditsFail();
}
private ParseSubscribedSubredditsListener mParseSubscribedSubredditsListener;
void parseSubscribedSubreddits(String response, ArrayList<SubredditData> subredditData,
void parseSubscribedSubreddits(String response, ArrayList<SubscribedSubredditData> subscribedSubredditData,
ArrayList<SubscribedUserData> subscribedUserData,
ParseSubscribedSubredditsListener parseSubscribedSubredditsListener) {
mParseSubscribedSubredditsListener = parseSubscribedSubredditsListener;
new ParseSubscribedSubredditsAsyncTask(response, subredditData).execute();
new ParseSubscribedSubredditsAsyncTask(response, subscribedSubredditData, subscribedUserData).execute();
}
private class ParseSubscribedSubredditsAsyncTask extends AsyncTask<Void, Void, Void> {
private JSONObject jsonResponse;
private boolean parseFailed;
private String lastItem;
private ArrayList<SubredditData> subredditData;
private ArrayList<SubredditData> newSubredditData;
private ArrayList<SubscribedSubredditData> subscribedSubredditData;
private ArrayList<SubscribedUserData> subscribedUserData;
private ArrayList<SubscribedSubredditData> newSubscribedSubredditData;
private ArrayList<SubscribedUserData> newSubscribedUserData;
ParseSubscribedSubredditsAsyncTask(String response, ArrayList<SubredditData> subredditData){
ParseSubscribedSubredditsAsyncTask(String response, ArrayList<SubscribedSubredditData> subscribedSubredditData,
ArrayList<SubscribedUserData> subscribedUserData){
try {
jsonResponse = new JSONObject(response);
parseFailed = false;
this.subredditData = subredditData;
newSubredditData = new ArrayList<>();
this.subscribedSubredditData = subscribedSubredditData;
this.subscribedUserData = subscribedUserData;
newSubscribedSubredditData = new ArrayList<>();
newSubscribedUserData = new ArrayList<>();
} catch (JSONException e) {
Log.i("user info json error", e.getMessage());
mParseSubscribedSubredditsListener.onParseSubscribedSubredditsFail();
@ -49,7 +57,18 @@ class ParseSubscribedSubreddits {
for(int i = 0; i < children.length(); i++) {
String name = children.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.DISPLAY_NAME);
String iconUrl = children.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.ICON_IMG_KEY);
newSubredditData.add(new SubredditData(name, iconUrl));
String id = children.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.NAME_KEY);
if(iconUrl.equals("null")) {
iconUrl = "";
}
if(children.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.SUBREDDIT_TYPE_KEY)
.equals(JSONUtils.SUBREDDIT_TYPE_VALUE_USER)) {
//It's a user
newSubscribedUserData.add(new SubscribedUserData(id, name.substring(2), iconUrl));
} else {
newSubscribedSubredditData.add(new SubscribedSubredditData(id, name, iconUrl));
}
}
lastItem = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.AFTER_KEY);
} catch (JSONException e) {
@ -62,8 +81,10 @@ class ParseSubscribedSubreddits {
@Override
protected void onPostExecute(Void aVoid) {
if(!parseFailed) {
subredditData.addAll(newSubredditData);
mParseSubscribedSubredditsListener.onParseSubscribedSubredditsSuccess(subredditData, lastItem);
subscribedSubredditData.addAll(newSubscribedSubredditData);
subscribedUserData.addAll(newSubscribedUserData);
mParseSubscribedSubredditsListener.onParseSubscribedSubredditsSuccess(subscribedSubredditData,
subscribedUserData, lastItem);
} else {
mParseSubscribedSubredditsListener.onParseSubscribedSubredditsFail();
}

View File

@ -1,50 +0,0 @@
package ml.docilealligator.infinityforreddit;
import android.os.Parcel;
import android.os.Parcelable;
class SubredditData implements Parcelable {
private String name;
private String iconUrl;
SubredditData(String name, String iconUrl) {
this.name = name;
this.iconUrl = iconUrl;
}
protected SubredditData(Parcel in) {
name = in.readString();
iconUrl = in.readString();
}
public static final Creator<SubredditData> CREATOR = new Creator<SubredditData>() {
@Override
public SubredditData createFromParcel(Parcel in) {
return new SubredditData(in);
}
@Override
public SubredditData[] newArray(int size) {
return new SubredditData[size];
}
};
public String getName() {
return name;
}
public String getIconUrl() {
return iconUrl;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(name);
parcel.writeString(iconUrl);
}
}

View File

@ -0,0 +1,21 @@
package ml.docilealligator.infinityforreddit;
import android.arch.lifecycle.LiveData;
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.OnConflictStrategy;
import android.arch.persistence.room.Query;
import java.util.List;
@Dao
public interface SubscribedSubredditDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(SubscribedSubredditData subscribedSubredditData);
@Query("DELETE FROM subscribed_subreddits")
void deleteAllSubscribedSubreddits();
@Query("SELECT * from subscribed_subreddits ORDER BY name COLLATE NOCASE ASC")
LiveData<List<SubscribedSubredditData>> getAllSubscribedSubreddits();
}

View File

@ -0,0 +1,38 @@
package ml.docilealligator.infinityforreddit;
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.PrimaryKey;
import android.support.annotation.NonNull;
@Entity(tableName = "subscribed_subreddits")
class SubscribedSubredditData {
@PrimaryKey
@NonNull
@ColumnInfo(name = "id")
private String id;
@ColumnInfo(name = "name")
private String name;
@ColumnInfo(name = "icon")
private String iconUrl;
SubscribedSubredditData(@NonNull String id, String name, String iconUrl) {
this.id = id;
this.name = name;
this.iconUrl = iconUrl;
}
@NonNull
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getIconUrl() {
return iconUrl;
}
}

View File

@ -11,18 +11,17 @@ import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import java.util.ArrayList;
import java.util.List;
import de.hdodenhof.circleimageview.CircleImageView;
class SubscribedSubredditRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
Context mContext;
ArrayList<SubredditData> mSubredditData;
RequestManager glide;
private Context mContext;
private List<SubscribedSubredditData> mSubscribedSubredditData;
private RequestManager glide;
SubscribedSubredditRecyclerViewAdapter(Context context, ArrayList<SubredditData> subredditData) {
SubscribedSubredditRecyclerViewAdapter(Context context) {
mContext = context;
mSubredditData = subredditData;
glide = Glide.with(context);
}
@ -34,17 +33,20 @@ class SubscribedSubredditRecyclerViewAdapter extends RecyclerView.Adapter<Recycl
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
if(!mSubredditData.get(i).getIconUrl().equals("")) {
glide.load(mSubredditData.get(i).getIconUrl()).into(((SubredditViewHolder) viewHolder).iconCircleImageView);
if(!mSubscribedSubredditData.get(i).getIconUrl().equals("")) {
glide.load(mSubscribedSubredditData.get(i).getIconUrl()).into(((SubredditViewHolder) viewHolder).iconCircleImageView);
} else {
glide.load(R.drawable.subreddit_default_icon).into(((SubredditViewHolder) viewHolder).iconCircleImageView);
}
((SubredditViewHolder) viewHolder).subredditNameTextView.setText(mSubredditData.get(i).getName());
((SubredditViewHolder) viewHolder).subredditNameTextView.setText(mSubscribedSubredditData.get(i).getName());
}
@Override
public int getItemCount() {
return mSubredditData.size();
if(mSubscribedSubredditData != null) {
return mSubscribedSubredditData.size();
}
return 0;
}
@Override
@ -52,9 +54,15 @@ class SubscribedSubredditRecyclerViewAdapter extends RecyclerView.Adapter<Recycl
glide.clear(((SubredditViewHolder) holder).iconCircleImageView);
}
void setSubscribedSubreddits(List<SubscribedSubredditData> subscribedSubreddits){
mSubscribedSubredditData = subscribedSubreddits;
notifyDataSetChanged();
}
private class SubredditViewHolder extends RecyclerView.ViewHolder {
private CircleImageView iconCircleImageView;
private TextView subredditNameTextView;
private final CircleImageView iconCircleImageView;
private final TextView subredditNameTextView;
public SubredditViewHolder(View itemView) {
super(itemView);

View File

@ -0,0 +1,41 @@
package ml.docilealligator.infinityforreddit;
import android.app.Application;
import android.arch.lifecycle.LiveData;
import android.os.AsyncTask;
import java.util.List;
public class SubscribedSubredditRepository {
private SubscribedSubredditDao mSubscribedSubredditDao;
private LiveData<List<SubscribedSubredditData>> mAllSubscribedSubreddits;
SubscribedSubredditRepository(Application application) {
SubscribedSubredditRoomDatabase db = SubscribedSubredditRoomDatabase.getDatabase(application);
mSubscribedSubredditDao = db.subscribedSubredditDao();
mAllSubscribedSubreddits = mSubscribedSubredditDao.getAllSubscribedSubreddits();
}
LiveData<List<SubscribedSubredditData>> getAllSubscribedSubreddits() {
return mAllSubscribedSubreddits;
}
public void insert(SubscribedSubredditData subscribedSubredditData) {
new insertAsyncTask(mSubscribedSubredditDao).execute(subscribedSubredditData);
}
private static class insertAsyncTask extends AsyncTask<SubscribedSubredditData, Void, Void> {
private SubscribedSubredditDao mAsyncTaskDao;
insertAsyncTask(SubscribedSubredditDao dao) {
mAsyncTaskDao = dao;
}
@Override
protected Void doInBackground(final SubscribedSubredditData... params) {
mAsyncTaskDao.insert(params[0]);
return null;
}
}
}

View File

@ -0,0 +1,26 @@
package ml.docilealligator.infinityforreddit;
import android.arch.persistence.room.Database;
import android.arch.persistence.room.Room;
import android.arch.persistence.room.RoomDatabase;
import android.content.Context;
@Database(entities = {SubscribedSubredditData.class}, version = 1)
public abstract class SubscribedSubredditRoomDatabase extends RoomDatabase {
private static SubscribedSubredditRoomDatabase INSTANCE;
public abstract SubscribedSubredditDao subscribedSubredditDao();
public static SubscribedSubredditRoomDatabase getDatabase(final Context context) {
if(INSTANCE == null) {
synchronized (SubscribedSubredditRoomDatabase.class) {
if(INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
SubscribedSubredditRoomDatabase.class, "subscribed_subreddits")
.build();
}
}
}
return INSTANCE;
}
}

View File

@ -0,0 +1,26 @@
package ml.docilealligator.infinityforreddit;
import android.app.Application;
import android.arch.lifecycle.AndroidViewModel;
import android.arch.lifecycle.LiveData;
import java.util.List;
public class SubscribedSubredditViewModel extends AndroidViewModel {
private SubscribedSubredditRepository mSubscribedSubredditRepository;
private LiveData<List<SubscribedSubredditData>> mAllSubscribedSubreddits;
public SubscribedSubredditViewModel(Application application) {
super(application);
mSubscribedSubredditRepository = new SubscribedSubredditRepository(application);
mAllSubscribedSubreddits = mSubscribedSubredditRepository.getAllSubscribedSubreddits();
}
public LiveData<List<SubscribedSubredditData>> getAllSubscribedSubreddits() {
return mAllSubscribedSubreddits;
}
public void insert(SubscribedSubredditData subscribedSubredditData) {
mSubscribedSubredditRepository.insert(subscribedSubredditData);
}
}

View File

@ -0,0 +1,21 @@
package ml.docilealligator.infinityforreddit;
import android.arch.lifecycle.LiveData;
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.OnConflictStrategy;
import android.arch.persistence.room.Query;
import java.util.List;
@Dao
public interface SubscribedUserDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(SubscribedUserData subscribedUserData);
@Query("DELETE FROM subscribed_users")
void deleteAllSubscribedUsers();
@Query("SELECT * from subscribed_users ORDER BY name COLLATE NOCASE ASC")
LiveData<List<SubscribedUserData>> getAllSubscribedUsers();
}

View File

@ -0,0 +1,37 @@
package ml.docilealligator.infinityforreddit;
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.PrimaryKey;
import android.support.annotation.NonNull;
@Entity(tableName = "subscribed_users")
class SubscribedUserData {
@PrimaryKey
@NonNull
@ColumnInfo(name = "id")
private String id;
@ColumnInfo(name = "name")
private String name;
@ColumnInfo(name = "icon")
private String iconUrl;
SubscribedUserData(@NonNull String id, String name, String iconUrl) {
this.id = id;
this.name = name;
this.iconUrl = iconUrl;
}
@NonNull
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getIconUrl() {
return iconUrl;
}
}

View File

@ -0,0 +1,73 @@
package ml.docilealligator.infinityforreddit;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import java.util.List;
import de.hdodenhof.circleimageview.CircleImageView;
class SubscribedUserRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context mContext;
private List<SubscribedUserData> mSubscribedUserData;
private RequestManager glide;
SubscribedUserRecyclerViewAdapter(Context context) {
mContext = context;
glide = Glide.with(context);
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
return new UserViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_subscribed_subreddit, viewGroup, false));
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
if(!mSubscribedUserData.get(i).getIconUrl().equals("")) {
glide.load(mSubscribedUserData.get(i).getIconUrl()).into(((UserViewHolder) viewHolder).iconCircleImageView);
} else {
glide.load(R.drawable.subreddit_default_icon).into(((UserViewHolder) viewHolder).iconCircleImageView);
}
((UserViewHolder) viewHolder).subredditNameTextView.setText(mSubscribedUserData.get(i).getName());
}
@Override
public int getItemCount() {
if(mSubscribedUserData != null) {
return mSubscribedUserData.size();
}
return 0;
}
@Override
public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
glide.clear(((UserViewHolder) holder).iconCircleImageView);
}
void setSubscribedUsers(List<SubscribedUserData> subscribedUsers){
mSubscribedUserData = subscribedUsers;
notifyDataSetChanged();
}
private class UserViewHolder extends RecyclerView.ViewHolder {
private final CircleImageView iconCircleImageView;
private final TextView subredditNameTextView;
public UserViewHolder(View itemView) {
super(itemView);
iconCircleImageView = itemView.findViewById(R.id.subreddit_icon_circle_image_view_item_subscribed_subreddit);
subredditNameTextView = itemView.findViewById(R.id.subreddit_name_text_view_item_subscribed_subreddit);
}
}
}

View File

@ -0,0 +1,41 @@
package ml.docilealligator.infinityforreddit;
import android.app.Application;
import android.arch.lifecycle.LiveData;
import android.os.AsyncTask;
import java.util.List;
public class SubscribedUserRepository {
private SubscribedUserDao mSubscribedUserDao;
private LiveData<List<SubscribedUserData>> mAllSubscribedUsers;
SubscribedUserRepository(Application application) {
SubscribedUserRoomDatabase db = SubscribedUserRoomDatabase.getDatabase(application);
mSubscribedUserDao = db.subscribedUserDao();
mAllSubscribedUsers = mSubscribedUserDao.getAllSubscribedUsers();
}
LiveData<List<SubscribedUserData>> getAllSubscribedSubreddits() {
return mAllSubscribedUsers;
}
public void insert(SubscribedUserData subscribedUserData) {
new SubscribedUserRepository.insertAsyncTask(mSubscribedUserDao).execute(subscribedUserData);
}
private static class insertAsyncTask extends AsyncTask<SubscribedUserData, Void, Void> {
private SubscribedUserDao mAsyncTaskDao;
insertAsyncTask(SubscribedUserDao dao) {
mAsyncTaskDao = dao;
}
@Override
protected Void doInBackground(final SubscribedUserData... params) {
mAsyncTaskDao.insert(params[0]);
return null;
}
}
}

View File

@ -0,0 +1,26 @@
package ml.docilealligator.infinityforreddit;
import android.arch.persistence.room.Database;
import android.arch.persistence.room.Room;
import android.arch.persistence.room.RoomDatabase;
import android.content.Context;
@Database(entities = {SubscribedUserData.class}, version = 1)
public abstract class SubscribedUserRoomDatabase extends RoomDatabase {
private static SubscribedUserRoomDatabase INSTANCE;
public abstract SubscribedUserDao subscribedUserDao();
public static SubscribedUserRoomDatabase getDatabase(final Context context) {
if(INSTANCE == null) {
synchronized (SubscribedUserRoomDatabase.class) {
if(INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
SubscribedUserRoomDatabase.class, "subscribed_users")
.build();
}
}
}
return INSTANCE;
}
}

View File

@ -0,0 +1,26 @@
package ml.docilealligator.infinityforreddit;
import android.app.Application;
import android.arch.lifecycle.AndroidViewModel;
import android.arch.lifecycle.LiveData;
import java.util.List;
public class SubscribedUserViewModel extends AndroidViewModel {
private SubscribedUserRepository mSubscribedUserRepository;
private LiveData<List<SubscribedUserData>> mAllSubscribedUsers;
public SubscribedUserViewModel(Application application) {
super(application);
mSubscribedUserRepository = new SubscribedUserRepository(application);
mAllSubscribedUsers = mSubscribedUserRepository.getAllSubscribedSubreddits();
}
public LiveData<List<SubscribedUserData>> getAllSubscribedUsers() {
return mAllSubscribedUsers;
}
public void insert(SubscribedUserData subscribedUserData) {
mSubscribedUserRepository.insert(subscribedUserData);
}
}

View File

@ -13,64 +13,83 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true">
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include
android:id="@+id/nav_header_main_activity"
layout="@layout/nav_header_main" />
<LinearLayout
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:clickable="true"
android:focusable="true"
android:background="?attr/selectableItemBackground">
android:layout_height="match_parent">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="32dp"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_account_circle_grey_24dp"/>
<TextView
android:layout_width="wrap_content"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/profile"
android:textColor="@android:color/black"
android:layout_gravity="center_vertical"/>
android:orientation="vertical">
</LinearLayout>
<include
android:id="@+id/nav_header_main_activity"
layout="@layout/nav_header_main" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#E0E0E0"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:clickable="true"
android:focusable="true"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/subscriptions"
android:layout_margin="16dp"/>
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="32dp"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_account_circle_grey_24dp"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/subscribed_subreddit_recycler_view_main_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/profile"
android:textColor="@android:color/black"
android:layout_gravity="center_vertical"/>
</LinearLayout>
</LinearLayout>
</android.support.design.widget.NavigationView>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#E0E0E0"/>
<TextView
android:id="@+id/following_label_main_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/following"
android:layout_margin="16dp"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/subscribed_user_recycler_view_main_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/subscriptions_label_main_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/subscriptions"
android:layout_margin="16dp"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/subscribed_subreddit_recycler_view_main_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>

View File

@ -17,5 +17,6 @@
<string name="karma_info">Karma: %1$d</string>
<string name="profile">Profile</string>
<string name="following">Following</string>
<string name="subscriptions">Subscriptions</string>
</resources>

View File

@ -25,3 +25,8 @@ allprojects {
task clean(type: Delete) {
delete rootProject.buildDir
}
ext {
roomVersion = '1.1.1'
archLifecycleVersion = '1.1.1'
}