diff options
author | Raghul Jagannathan <raghul@redmart.com> | 2015-05-27 08:31:42 +0800 |
---|---|---|
committer | Raghul Jagannathan <raghul@redmart.com> | 2015-05-27 08:31:42 +0800 |
commit | d0022e053e4abfe35dac4ae2d90c6960982181fd (patch) | |
tree | a03a02dda68d9956e07759aad87cc9991d0b8b97 /app/src | |
parent | ba036e14990a6dd7e8a5076bdc20176532a4f417 (diff) | |
download | AntennaPod-d0022e053e4abfe35dac4ae2d90c6960982181fd.zip |
Subscription view for managing feeds and Navigation drawer feed list cleanup
Diffstat (limited to 'app/src')
12 files changed, 462 insertions, 9 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java index d62612c76..e3a48c050 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java @@ -23,12 +23,6 @@ import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; - -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.Validate; - -import java.util.List; - import de.danoeh.antennapod.R; import de.danoeh.antennapod.adapter.NavListAdapter; import de.danoeh.antennapod.core.feed.EventDistributor; @@ -45,9 +39,13 @@ import de.danoeh.antennapod.fragment.ItemlistFragment; import de.danoeh.antennapod.fragment.NewEpisodesFragment; import de.danoeh.antennapod.fragment.PlaybackHistoryFragment; import de.danoeh.antennapod.fragment.QueueFragment; +import de.danoeh.antennapod.fragment.SubscriptionFragment; import de.danoeh.antennapod.menuhandler.NavDrawerActivity; import de.danoeh.antennapod.preferences.PreferenceController; import de.greenrobot.event.EventBus; +import java.util.List; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.Validate; /** * The activity that is shown when the user launches the app. @@ -79,6 +77,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity AllEpisodesFragment.TAG, DownloadsFragment.TAG, PlaybackHistoryFragment.TAG, + SubscriptionFragment.TAG, AddFeedFragment.TAG }; @@ -282,6 +281,11 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity case AddFeedFragment.TAG: fragment = new AddFeedFragment(); break; + case SubscriptionFragment.TAG: + SubscriptionFragment subscriptionFragment = new SubscriptionFragment(); + subscriptionFragment.setItemAccess(itemAccess); + fragment = subscriptionFragment; + break; } currentTitle = navAdapter.getLabel(tag); getSupportActionBar().setTitle(currentTitle); @@ -292,6 +296,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity loadFragment(fragment); } + private void loadFeedFragmentByPosition(int relPos, Bundle args) { if(relPos < 0) { return; @@ -305,7 +310,15 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity saveLastNavFragment(String.valueOf(feed.getId())); currentTitle = ""; getSupportActionBar().setTitle(currentTitle); - loadFragment(fragment); + loadChildFragment(fragment); + } + + private void loadFeedFragment(Feed feed){ + long feedId = feed.getId(); + Fragment fragment = ItemlistFragment.newInstance(feedId); + currentTitle = ""; + getSupportActionBar().setTitle(currentTitle); + loadChildFragment(fragment); } public void loadFeedFragmentById(long feedId) { @@ -537,7 +550,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity String lastFragment = getLastNavFragment(); if(!ArrayUtils.contains(NAV_DRAWER_TAGS, lastFragment)) { long feedId = Long.valueOf(lastFragment); - loadFeedFragmentById(feedId); + //loadFeedFragmentById(feedId); saveLastNavFragment(null); } @@ -560,6 +573,10 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity loadData(); } + public void onEvent(SubscriptionFragment.SubscriptionEvent event){ + loadFeedFragment(event.feed); + } + private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() { @Override @@ -593,4 +610,15 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity super.onNewIntent(intent); setIntent(intent); } + + @Override + public void onBackPressed() { + // Make sure to have consistent behaviour across android apps + // Close the nav drawer if open on the first back button press + if(drawerLayout.isDrawerOpen(navDrawer)){ + drawerLayout.closeDrawer(navDrawer); + return; + } + super.onBackPressed(); + } } diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java index 13982f57d..81d997d65 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java @@ -16,6 +16,7 @@ import android.widget.TextView; import com.squareup.picasso.Picasso; +import de.danoeh.antennapod.fragment.SubscriptionFragment; import org.apache.commons.lang3.ArrayUtils; import java.util.ArrayList; @@ -100,6 +101,9 @@ public class NavListAdapter extends BaseAdapter case PlaybackHistoryFragment.TAG: icon = R.attr.ic_history; break; + case SubscriptionFragment.TAG: + icon = R.attr.ic_folder; + break; case AddFeedFragment.TAG: icon = R.attr.content_new; break; @@ -119,7 +123,7 @@ public class NavListAdapter extends BaseAdapter @Override public int getCount() { - return getSubscriptionOffset() + itemAccess.getCount(); + return getSubscriptionOffset() ;//+ itemAccess.getCount(); //Avoid feed } @Override diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java new file mode 100644 index 000000000..5928ad119 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java @@ -0,0 +1,70 @@ +package de.danoeh.antennapod.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; + +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.feed.Feed; +import de.danoeh.antennapod.view.SubscriptionViewItem; + +/** + * Adapter for subscriptions + */ +public class SubscriptionsAdapter extends BaseAdapter { + + private NavListAdapter.ItemAccess mItemAccess; + + private Context mContext; + + public SubscriptionsAdapter(Context context, NavListAdapter.ItemAccess itemAccess) { + mItemAccess = itemAccess; + mContext = context; + } + + public void setItemAccess(NavListAdapter.ItemAccess itemAccess) { + mItemAccess = itemAccess; + } + + @Override + public int getCount() { + return mItemAccess.getCount(); + } + + @Override + public Object getItem(int position) { + return mItemAccess.getItem(position); + } + + @Override + public long getItemId(int position) { + return 0; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + Holder holder; + final Feed item = (Feed) getItem(position); + if (item == null) return null; + + if (convertView == null) { + holder = new Holder(); + LayoutInflater inflater = + (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + convertView = inflater.inflate(R.layout.subscription_item, parent, false); + holder.itemView = (SubscriptionViewItem) convertView.findViewById(R.id.subscription_item); + convertView.setTag(holder); + } else { + holder = (Holder) convertView.getTag(); + } + + holder.itemView.setFeed(item, mItemAccess.getNumberOfUnreadFeedItems(item.getId())); + return convertView; + } + + static class Holder { + SubscriptionViewItem itemView; + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java new file mode 100644 index 000000000..999da10ab --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java @@ -0,0 +1,108 @@ +package de.danoeh.antennapod.fragment; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.GridView; + +import java.util.ArrayList; +import java.util.List; + +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.activity.MainActivity; +import de.danoeh.antennapod.adapter.NavListAdapter; +import de.danoeh.antennapod.adapter.SubscriptionsAdapter; +import de.danoeh.antennapod.core.feed.Feed; +import de.danoeh.antennapod.core.storage.DBReader; +import de.greenrobot.event.EventBus; +import rx.Observable; +import rx.functions.Action1; + +/** + * Fragment for displaying feed subscriptions + */ +public class SubscriptionFragment extends Fragment { + + public static final String TAG = "SubscriptionFragment"; + + private GridView mSubscriptionGridLayout; + private DBReader.NavDrawerData mDrawerData; + private SubscriptionsAdapter mSubscriptionAdapter; + private NavListAdapter.ItemAccess mItemAccess; + + private List<Feed> mSubscriptionList = new ArrayList<>(); + + + public SubscriptionFragment() { + } + + + public void setItemAccess(NavListAdapter.ItemAccess itemAccess) { + mItemAccess = itemAccess; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setRetainInstance(true); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View root = inflater.inflate(R.layout.fragment_subscriptions, container, false); + mSubscriptionGridLayout = (GridView) root.findViewById(R.id.subscriptions_grid); + return root; + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + mSubscriptionAdapter = new SubscriptionsAdapter(getActivity(), mItemAccess); + + mSubscriptionGridLayout.setAdapter(mSubscriptionAdapter); + + Observable.just(loadData()).subscribe(new Action1<DBReader.NavDrawerData>() { + @Override + public void call(DBReader.NavDrawerData navDrawerData) { + mDrawerData = navDrawerData; + mSubscriptionList = mDrawerData.feeds; + mSubscriptionAdapter.setItemAccess(mItemAccess); + mSubscriptionAdapter.notifyDataSetChanged(); + } + }); + + mSubscriptionGridLayout.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView<?> parent, View view, int position, long id) { + EventBus.getDefault().post(new SubscriptionEvent(mSubscriptionList.get(position))); + } + }); + + if (getActivity() instanceof MainActivity) { + ((MainActivity) getActivity()).getSupportActionBar().setTitle(R.string.my_subscriptions); + } + + } + + @Override + public void onResume() { + super.onResume(); + } + + public class SubscriptionEvent { + public final Feed feed; + + SubscriptionEvent(Feed f) { + feed = f; + } + } + + + private DBReader.NavDrawerData loadData() { + return DBReader.getNavDrawerData(getActivity()); + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/utils/TimeUtils.java b/app/src/main/java/de/danoeh/antennapod/utils/TimeUtils.java new file mode 100644 index 000000000..bb0573e72 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/utils/TimeUtils.java @@ -0,0 +1,64 @@ +package de.danoeh.antennapod.utils; + + +import android.content.Context; + +import java.util.Date; + +import de.danoeh.antennapod.R; + +/* + * Copyright 2012 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//http://stackoverflow.com/questions/13018550/time-since-ago-library-for-android-java + + +public class TimeUtils { + private static final int SECOND_MILLIS = 1000; + private static final int MINUTE_MILLIS = 60 * SECOND_MILLIS; + private static final int HOUR_MILLIS = 60 * MINUTE_MILLIS; + private static final int DAY_MILLIS = 24 * HOUR_MILLIS; + + + public static String getTimeAgo(long time, Context ctx) { + if (time < 1000000000000L) { + // if timestamp given in seconds, convert to millis + time *= 1000; + } + + long now = new Date().getTime(); + if (time > now || time <= 0) { + return null; + } + + final long diff = now - time; + if (diff < MINUTE_MILLIS) { + return ctx.getString(R.string.time_just_now); + } else if (diff < 2 * MINUTE_MILLIS) { + return ctx.getString(R.string.time_a_min_ago); + } else if (diff < 50 * MINUTE_MILLIS) { + return diff / MINUTE_MILLIS + ctx.getString(R.string.time_min_ago); + } else if (diff < 90 * MINUTE_MILLIS) { + return ctx.getString(R.string.time_an_hour_ago); + } else if (diff < 24 * HOUR_MILLIS) { + return diff / HOUR_MILLIS + ctx.getString(R.string.time_hours_ago); + } else if (diff < 48 * HOUR_MILLIS) { + return ctx.getString(R.string.time_yesterday); + } else { + return diff / DAY_MILLIS + ctx.getString(R.string.time_days_ago); + } + } +}
\ No newline at end of file diff --git a/app/src/main/java/de/danoeh/antennapod/view/SubscriptionViewItem.java b/app/src/main/java/de/danoeh/antennapod/view/SubscriptionViewItem.java new file mode 100644 index 000000000..1aca68610 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/view/SubscriptionViewItem.java @@ -0,0 +1,63 @@ +package de.danoeh.antennapod.view; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ImageView; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import com.squareup.picasso.Picasso; + +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.feed.Feed; +import de.danoeh.antennapod.utils.TimeUtils; + +/** + * Custom view for handling feed item. + */ +public class SubscriptionViewItem extends RelativeLayout { + + private ImageView mImageView; + private TextView mTitle; + private TextView mUnreadCountText; + private Context mContext; + + public SubscriptionViewItem(Context context) { + super(context); + init(context); + } + + public SubscriptionViewItem(Context context, AttributeSet attrs) { + super(context, attrs); + init(context); + } + + public SubscriptionViewItem(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(context); + } + + @Override + public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, widthMeasureSpec); + } + + private void init(Context context) { + mContext = context; + LayoutInflater mLayoutInflater = + (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View view = mLayoutInflater.inflate(R.layout.subscription_view, this); + mTitle = (TextView) view.findViewById(R.id.txtvTitle); + mImageView = (ImageView) view.findViewById(R.id.imgvCover); + mUnreadCountText = (TextView) view.findViewById(R.id.unread_count_text); + } + + public void setFeed(Feed feed, int unreadCount) { + Picasso.with(mContext).load(feed.getImageUri()).centerCrop().fit().into(mImageView); + mUnreadCountText.setText(unreadCount + ""); + mTitle.setText(TimeUtils.getTimeAgo(feed.getLastUpdate().getTime(), mContext)); + } + +} diff --git a/app/src/main/res/drawable/cover_image_bg.xml b/app/src/main/res/drawable/cover_image_bg.xml new file mode 100644 index 000000000..cf4c3e9f1 --- /dev/null +++ b/app/src/main/res/drawable/cover_image_bg.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<shape xmlns:android="http://schemas.android.com/apk/res/android"> + <gradient + android:type="linear" + android:centerX="69%" + android:startColor="#00000000" + android:centerColor="#59000000" + android:endColor="#FF242424" + android:angle="270"/> +</shape>
\ No newline at end of file diff --git a/app/src/main/res/drawable/unread_circle.xml b/app/src/main/res/drawable/unread_circle.xml new file mode 100644 index 000000000..c31e753b1 --- /dev/null +++ b/app/src/main/res/drawable/unread_circle.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="oval"> + + + <stroke + android:width="1dp" + android:color="@color/white"/> + +</shape>
\ No newline at end of file diff --git a/app/src/main/res/layout/fragment_subscriptions.xml b/app/src/main/res/layout/fragment_subscriptions.xml new file mode 100644 index 000000000..8a61e5fa5 --- /dev/null +++ b/app/src/main/res/layout/fragment_subscriptions.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <GridView + android:id="@+id/subscriptions_grid" + android:layout_width="match_parent" + android:numColumns="3" + android:horizontalSpacing="2dp" + android:verticalSpacing="2dp" + android:layout_height="match_parent" + android:layout_gravity="center_horizontal"> + </GridView> +</LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/subscription_item.xml b/app/src/main/res/layout/subscription_item.xml new file mode 100644 index 000000000..fc89ab74d --- /dev/null +++ b/app/src/main/res/layout/subscription_item.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + + <de.danoeh.antennapod.view.SubscriptionViewItem + android:layout_width="match_parent" + android:id="@+id/subscription_item" + android:layout_height="match_parent"/> + +</RelativeLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/subscription_view.xml b/app/src/main/res/layout/subscription_view.xml new file mode 100644 index 000000000..fad32799c --- /dev/null +++ b/app/src/main/res/layout/subscription_view.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <ImageView + android:id="@+id/imgvCover" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:layout_centerHorizontal="true" + android:layout_centerVertical="true" + android:src="@drawable/ic_launcher" /> + + <RelativeLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@drawable/cover_image_bg"> + + </RelativeLayout> + + <TextView + android:id="@+id/txtvTitle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentBottom="true" + android:layout_alignParentEnd="true" + android:layout_alignParentRight="true" + android:layout_margin="5dp" + android:ellipsize="end" + android:maxLines="1" + android:text="@string/app_name" + android:textColor="@color/white" + android:textSize="12sp" /> + + <RelativeLayout + android:layout_width="18dp" + android:layout_height="18dp" + android:layout_alignParentBottom="true" + android:layout_margin="5dp" + android:background="@drawable/unread_circle"> + + <TextView + android:id="@+id/unread_count_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerHorizontal="true" + android:layout_centerInParent="true" + android:ellipsize="end" + android:maxLines="1" + android:text="3" + android:textColor="@color/white" + android:textSize="11sp" /> + + </RelativeLayout> + + +</RelativeLayout>
\ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 000000000..9c055f887 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="time_just_now">just now</string> + <string name="time_a_min_ago">a min ago</string> + <string name="time_an_hour_ago">an hour ago</string> + <string name="time_min_ago">" min ago"</string> + <string name="time_yesterday">yesterday</string> + <string name="time_hours_ago">" hours ago"</string> + <string name="time_days_ago">" days ago"</string> +</resources>
\ No newline at end of file |