Add manage feeds activity with basic feed layout

This commit is contained in:
Shinokuni 2019-02-23 17:13:10 +00:00
parent e0232ce0fc
commit 32833706b2
26 changed files with 354 additions and 32 deletions

View File

@ -18,7 +18,7 @@
<PersistentState>
<option name="values">
<map>
<entry key="url" value="jar:file:/Applications/Android%20Studio.app/Contents/plugins/android/lib/android.jar!/images/material_design_icons/file/ic_folder_black_24dp.xml" />
<entry key="url" value="jar:file:/Applications/Android%20Studio.app/Contents/plugins/android/lib/android.jar!/images/material_design_icons/action/ic_open_in_browser_black_24dp.xml" />
</map>
</option>
</PersistentState>
@ -28,8 +28,7 @@
</option>
<option name="values">
<map>
<entry key="color" value="ffffff" />
<entry key="outputName" value="ic_folder_white" />
<entry key="outputName" value="ic_open_in_browser" />
<entry key="sourceFile" value="$USER_HOME$" />
</map>
</option>

Binary file not shown.

Binary file not shown.

View File

@ -55,4 +55,8 @@ dependencies {
implementation 'com.afollestad.material-dialogs:core:0.9.6.0'
implementation 'com.github.clans:fab:1.6.4'
// fastadapter requires androidx after 3.2.9
implementation 'com.mikepenz:fastadapter:3.2.9'
implementation 'com.mikepenz:fastadapter-commons:3.2.9'
}

View File

@ -15,6 +15,7 @@
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true"
tools:ignore="GoogleAppIndexingWarning">
<activity android:name=".ManageFeedsActivity"></activity>
<activity
android:name=".MainActivity"
android:theme="@style/AppTheme.NoActionBar">
@ -24,11 +25,10 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ItemActivity"
android:theme="@style/AppTheme.NoActionBar"
android:parentActivityName=".MainActivity">
</activity>
<activity
android:name=".ItemActivity"
android:parentActivityName=".MainActivity"
android:theme="@style/AppTheme.NoActionBar"></activity>
</application>
</manifest>

View File

@ -3,9 +3,8 @@ package com.readrops.app;
import android.app.Application;
import android.arch.lifecycle.LiveData;
import com.readrops.app.database.ItemWithFeed;
import com.readrops.app.database.pojo.ItemWithFeed;
import com.readrops.app.database.entities.Feed;
import com.readrops.app.database.entities.Item;
import com.readrops.readropslibrary.ParsingResult;
public class BasedRepository extends ARepository {

View File

@ -0,0 +1,80 @@
package com.readrops.app;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.mikepenz.fastadapter.FastAdapter;
import com.mikepenz.fastadapter.items.AbstractItem;
import com.mikepenz.fastadapter.items.ModelAbstractItem;
import com.readrops.app.database.pojo.FeedWithFolder;
import com.readrops.app.utils.GlideApp;
import java.util.List;
public class FeedWithFolderItem extends ModelAbstractItem<FeedWithFolder, FeedWithFolderItem, FeedWithFolderItem.ViewHolder> {
public FeedWithFolderItem(FeedWithFolder feedWithFolder) {
super(feedWithFolder);
}
@NonNull
@Override
public ViewHolder getViewHolder(View v) {
return new ViewHolder(v);
}
@Override
public int getType() {
return R.id.feed_layout;
}
@Override
public int getLayoutRes() {
return R.layout.feed_layout;
}
@Override
public void bindView(ViewHolder holder, List<Object> payloads) {
super.bindView(holder, payloads);
FeedWithFolder feedWithFolder = getModel();
if (feedWithFolder.getFeed().getIconUrl() != null) {
GlideApp.with(holder.itemView.getContext())
.load(feedWithFolder.getFeed().getIconUrl())
.diskCacheStrategy(DiskCacheStrategy.ALL)
.placeholder(R.drawable.ic_rss_feed)
.into(holder.feedIcon);
}
holder.feedName.setText(feedWithFolder.getFeed().getName());
if (feedWithFolder.getFeed().getDescription() != null) {
holder.feedDescription.setVisibility(View.VISIBLE);
holder.feedDescription.setText(feedWithFolder.getFeed().getDescription());
} else
holder.feedDescription.setVisibility(View.GONE);
holder.folderName.setText(feedWithFolder.getFolder().getName());
}
protected static class ViewHolder extends RecyclerView.ViewHolder {
private ImageView feedIcon;
private TextView feedName;
private TextView feedDescription;
private TextView folderName;
public ViewHolder(View itemView) {
super(itemView);
feedIcon = itemView.findViewById(R.id.feed_layout_icon);
feedName = itemView.findViewById(R.id.feed_layout_name);
feedDescription = itemView.findViewById(R.id.feed_layout_description);
folderName = itemView.findViewById(R.id.feed_layout_folder);
}
}
}

View File

@ -18,7 +18,7 @@ import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.readrops.app.database.ItemWithFeed;
import com.readrops.app.database.pojo.ItemWithFeed;
import com.readrops.app.database.entities.Item;
import com.readrops.app.utils.DateUtils;
import com.readrops.app.utils.GlideApp;

View File

@ -5,9 +5,7 @@ import android.arch.lifecycle.AndroidViewModel;
import android.arch.lifecycle.LiveData;
import android.support.annotation.NonNull;
import com.readrops.app.database.Database;
import com.readrops.app.database.ItemWithFeed;
import com.readrops.app.database.entities.Item;
import com.readrops.app.database.pojo.ItemWithFeed;
public class ItemViewModel extends AndroidViewModel {

View File

@ -6,7 +6,7 @@ import android.graphics.Bitmap;
import android.support.v7.graphics.Palette;
import android.util.Patterns;
import com.readrops.app.database.ItemWithFeed;
import com.readrops.app.database.pojo.ItemWithFeed;
import com.readrops.app.database.entities.Feed;
import com.readrops.app.database.entities.Item;
import com.readrops.app.utils.Utils;

View File

@ -26,7 +26,7 @@ import com.bumptech.glide.Glide;
import com.bumptech.glide.integration.recyclerview.RecyclerViewPreloader;
import com.bumptech.glide.util.ViewPreloadSizeProvider;
import com.github.clans.fab.FloatingActionMenu;
import com.readrops.app.database.ItemWithFeed;
import com.readrops.app.database.pojo.ItemWithFeed;
import com.readrops.app.database.entities.Item;
import com.readrops.app.utils.GlideApp;
import com.readrops.readropslibrary.ParsingResult;
@ -220,10 +220,13 @@ public class MainActivity extends AppCompatActivity implements SimpleCallback, S
public void addFolder(View view) {
actionMenu.close(true);
Intent intent = new Intent(this, ManageFeedsActivity.class);
startActivity(intent);
}
public void insertNewFeed(ParsingResult result) {
refreshLayout.setRefreshing(true);
viewModel.addFeed(result);
}
}

View File

@ -1,6 +1,5 @@
package com.readrops.app;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
@ -23,7 +22,7 @@ import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.transition.DrawableCrossFadeFactory;
import com.bumptech.glide.util.ViewPreloadSizeProvider;
import com.readrops.app.database.ItemWithFeed;
import com.readrops.app.database.pojo.ItemWithFeed;
import com.readrops.app.database.entities.Item;
import com.readrops.app.utils.DateUtils;
import com.readrops.app.utils.GlideRequests;

View File

@ -5,7 +5,7 @@ import android.arch.lifecycle.AndroidViewModel;
import android.arch.lifecycle.LiveData;
import android.support.annotation.NonNull;
import com.readrops.app.database.ItemWithFeed;
import com.readrops.app.database.pojo.ItemWithFeed;
import com.readrops.readropslibrary.ParsingResult;
import java.util.List;

View File

@ -0,0 +1,34 @@
package com.readrops.app;
import android.arch.lifecycle.ViewModelProvider;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import com.mikepenz.fastadapter.FastAdapter;
import com.mikepenz.fastadapter.adapters.ModelAdapter;
import com.readrops.app.database.pojo.FeedWithFolder;
public class ManageFeedsActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private ModelAdapter<FeedWithFolder, FeedWithFolderItem> itemAdapter;
private ManageFeedsViewModel viewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_feeds);
recyclerView = findViewById(R.id.feeds_recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
itemAdapter = new ModelAdapter<>(FeedWithFolderItem::new);
FastAdapter fastAdapter = FastAdapter.with(itemAdapter);
recyclerView.setAdapter(fastAdapter);
viewModel = ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication()).create(ManageFeedsViewModel.class);
viewModel.getFeedsWithFolder().observe(this, feedWithFolders -> itemAdapter.add(feedWithFolders));
}
}

View File

@ -0,0 +1,29 @@
package com.readrops.app;
import android.app.Application;
import android.app.ListActivity;
import android.arch.lifecycle.AndroidViewModel;
import android.arch.lifecycle.LiveData;
import android.support.annotation.NonNull;
import com.readrops.app.database.Database;
import com.readrops.app.database.pojo.FeedWithFolder;
import java.util.List;
public class ManageFeedsViewModel extends AndroidViewModel {
private Database db;
private LiveData<List<FeedWithFolder>> feedsWithFolder;
public ManageFeedsViewModel(@NonNull Application application) {
super(application);
db = Database.getInstance(application);
feedsWithFolder = db.feedDao().getAllFeedsWithFolder();
}
public LiveData<List<FeedWithFolder>> getFeedsWithFolder() {
return feedsWithFolder;
}
}

View File

@ -1,12 +1,14 @@
package com.readrops.app.database.dao;
import android.arch.lifecycle.LiveData;
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.Query;
import android.arch.persistence.room.Update;
import com.readrops.app.database.entities.Feed;
import com.readrops.app.database.pojo.FeedWithFolder;
import java.util.List;
@ -31,4 +33,8 @@ public interface FeedDao {
@Query("Update Feed set folder_id = :folderId Where id = :feedId")
void updateFeedFolder(int feedId, int folderId);
@Query("Select Feed.name as feed_name, Feed.id as feed_id, Folder.name as folder_name, Folder.id as folder_id," +
"Feed.description as feed_description, Feed.icon_url as feed_icon_url, Feed.url as feed_url" +
" from Feed Inner Join Folder on Feed.folder_id = Folder.id Order by Feed.name")
LiveData<List<FeedWithFolder>> getAllFeedsWithFolder();
}

View File

@ -6,7 +6,7 @@ import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.Query;
import com.readrops.app.database.ItemWithFeed;
import com.readrops.app.database.pojo.ItemWithFeed;
import com.readrops.app.database.entities.Item;
import java.util.List;

View File

@ -0,0 +1,31 @@
package com.readrops.app.database.pojo;
import android.arch.persistence.room.Embedded;
import com.readrops.app.database.entities.Feed;
import com.readrops.app.database.entities.Folder;
public class FeedWithFolder {
@Embedded(prefix = "feed_")
private Feed feed;
@Embedded(prefix = "folder_")
private Folder folder;
public Feed getFeed() {
return feed;
}
public void setFeed(Feed feed) {
this.feed = feed;
}
public Folder getFolder() {
return folder;
}
public void setFolder(Folder folder) {
this.folder = folder;
}
}

View File

@ -1,4 +1,4 @@
package com.readrops.app.database;
package com.readrops.app.database.pojo;
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Embedded;

View File

@ -3,24 +3,18 @@ package com.readrops.app.utils;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.webkit.WebSettings;
import android.webkit.WebView;
import com.readrops.app.R;
import com.readrops.app.database.ItemWithFeed;
import com.readrops.app.database.entities.Item;
import com.readrops.app.database.pojo.ItemWithFeed;
import com.readrops.readropslibrary.Utils.LibUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Attribute;
import org.jsoup.nodes.Attributes;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.util.Iterator;
public class ReadropsWebView extends WebView {
private ItemWithFeed itemWithFeed;

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M19,4L5,4c-1.11,0 -2,0.9 -2,2v12c0,1.1 0.89,2 2,2h4v-2L5,18L5,8h14v10h-4v2h4c1.1,0 2,-0.9 2,-2L21,6c0,-1.1 -0.89,-2 -2,-2zM12,10l-4,4h3v6h2v-6h3l-4,-4z"/>
</vector>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ManageFeedsActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/feeds_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listItem="@layout/feed_layout">
</android.support.v7.widget.RecyclerView>
</android.support.constraint.ConstraintLayout>

View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/feed_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:layout_marginTop="6dp"
android:layout_marginEnd="6dp"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="6dp">
<RelativeLayout
android:id="@+id/feed_layout_first_part"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/feed_layout_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentStart="true"
android:layout_marginEnd="6dp"
android:src="@drawable/ic_rss_feed" />
<TextView
android:id="@+id/feed_layout_name"
style="@style/Base.TextAppearance.AppCompat.Subhead"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/feed_layout_icon"
android:layout_toStartOf="@id/feed_layout_delete"
android:ellipsize="end"
android:maxLines="2"
android:minLines="1"
tools:text="Feed name" />
<TextView
android:id="@+id/feed_layout_description"
style="@style/Base.TextAppearance.AppCompat.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/feed_layout_icon"
android:layout_alignParentStart="true"
android:layout_marginTop="6dp"
android:ellipsize="end"
android:maxLines="3"
android:minLines="1"
android:visibility="visible"
tools:visibility="visible"
tools:text="This is a feed description" />
<ImageView
android:id="@+id/feed_layout_delete"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentEnd="true"
android:layout_marginStart="8dp"
android:src="@drawable/ic_delete" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:layout_below="@id/feed_layout_first_part">
<TextView
android:id="@+id/feed_layout_folder"
style="@style/Base.TextAppearance.AppCompat.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_toStartOf="@id/feed_layout_edit"
android:maxLines="1"
android:ellipsize="end"
tools:text="Folder 1" />
<ImageView
android:id="@+id/feed_layout_edit"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentEnd="true"
android:layout_marginStart="8dp"
android:src="@drawable/ic_edit" />
</RelativeLayout>
</RelativeLayout>
</android.support.v7.widget.CardView>

View File

@ -97,23 +97,23 @@
android:id="@+id/item_readtime_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/item_interpoint"
android:layout_marginStart="6dp"
android:layout_marginLeft="6dp"
android:layout_marginStart="6dp">
android:layout_toLeftOf="@id/item_interpoint">
<ImageView
android:id="@+id/item_readtime_icon"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@drawable/ic_read_time"/>
android:src="@drawable/ic_read_time" />
<TextView
android:id="@+id/item_readtime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/item_readtime_icon"
android:layout_marginStart="4dp"
android:layout_marginLeft="4dp"
android:layout_toRightOf="@id/item_readtime_icon"
tools:text="3 mins" />
</RelativeLayout>