summaryrefslogtreecommitdiff
path: root/app/src/main
diff options
context:
space:
mode:
authorH. Lehmann <ByteHamster@users.noreply.github.com>2019-10-02 15:46:29 +0200
committerGitHub <noreply@github.com>2019-10-02 15:46:29 +0200
commitf9fd9c32827dee1e45505d9edcee74aba525cd97 (patch)
tree68ff29feb9f39428f5a83c8ca0b79a3abb419a50 /app/src/main
parent8f5ff42f6a1a1a7d47e6c25bf9cc11e4b44b86f7 (diff)
parent6967e9c8902b789079c7dee6a78d835410716d60 (diff)
downloadAntennaPod-f9fd9c32827dee1e45505d9edcee74aba525cd97.zip
Merge pull request #3426 from ByteHamster/feedinfo-fragment
Feedinfo page animation
Diffstat (limited to 'app/src/main')
-rw-r--r--app/src/main/AndroidManifest.xml11
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java225
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/FeedSettingsActivity.java130
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java28
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java234
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java64
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java63
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/TransitionEffect.java5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/viewmodel/FeedSettingsViewModel.java30
-rw-r--r--app/src/main/res/anim/card_flip_left_in.xml25
-rw-r--r--app/src/main/res/anim/card_flip_left_out.xml18
-rw-r--r--app/src/main/res/anim/card_flip_right_in.xml25
-rw-r--r--app/src/main/res/anim/card_flip_right_out.xml18
-rw-r--r--app/src/main/res/values/integers.xml5
14 files changed, 435 insertions, 446 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index aa9dc96c4..bfef37f71 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -105,17 +105,6 @@
android:value="de.danoeh.antennapod.activity.MainActivity"/>
</activity>
- <activity
- android:name=".activity.FeedInfoActivity"
- android:label="@string/feed_info_label">
- </activity>
-
- <activity
- android:name=".activity.FeedSettingsActivity"
- android:windowSoftInputMode="stateHidden"
- android:label="@string/feed_settings_label">
- </activity>
-
<service
android:name=".core.service.PlayerWidgetJobService"
android:permission="android.permission.BIND_JOB_SERVICE"
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java
deleted file mode 100644
index 26e360bd3..000000000
--- a/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java
+++ /dev/null
@@ -1,225 +0,0 @@
-package de.danoeh.antennapod.activity;
-
-import android.content.ClipData;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.LightingColorFilter;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.bumptech.glide.Glide;
-import com.bumptech.glide.request.RequestOptions;
-import com.joanzapata.iconify.Iconify;
-
-import org.apache.commons.lang3.StringUtils;
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Document;
-
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
-import de.danoeh.antennapod.core.feed.Feed;
-import de.danoeh.antennapod.core.glide.ApGlideSettings;
-import de.danoeh.antennapod.core.glide.FastBlurTransformation;
-import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.core.storage.DBReader;
-import de.danoeh.antennapod.core.storage.DownloadRequestException;
-import de.danoeh.antennapod.core.util.IntentUtils;
-import de.danoeh.antennapod.core.util.LangUtils;
-import de.danoeh.antennapod.core.util.syndication.HtmlToPlainText;
-import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
-import io.reactivex.Maybe;
-import io.reactivex.MaybeOnSubscribe;
-import io.reactivex.android.schedulers.AndroidSchedulers;
-import io.reactivex.disposables.Disposable;
-import io.reactivex.schedulers.Schedulers;
-
-/**
- * Displays information about a feed.
- */
-public class FeedInfoActivity extends AppCompatActivity {
-
- public static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
- private static final String TAG = "FeedInfoActivity";
- private Feed feed;
-
- private ImageView imgvCover;
- private TextView txtvTitle;
- private TextView txtvDescription;
- private TextView lblLanguage;
- private TextView txtvLanguage;
- private TextView lblAuthor;
- private TextView txtvAuthor;
- private TextView txtvUrl;
-
- private Disposable disposable;
-
-
- private final View.OnClickListener copyUrlToClipboard = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if(feed != null && feed.getDownload_url() != null) {
- String url = feed.getDownload_url();
- ClipData clipData = ClipData.newPlainText(url, url);
- android.content.ClipboardManager cm = (android.content.ClipboardManager) FeedInfoActivity.this
- .getSystemService(Context.CLIPBOARD_SERVICE);
- cm.setPrimaryClip(clipData);
- Toast t = Toast.makeText(FeedInfoActivity.this, R.string.copied_url_msg, Toast.LENGTH_SHORT);
- t.show();
- }
- }
- };
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- setTheme(UserPreferences.getTheme());
- super.onCreate(savedInstanceState);
- setContentView(R.layout.feedinfo);
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
- long feedId = getIntent().getLongExtra(EXTRA_FEED_ID, -1);
-
- imgvCover = findViewById(R.id.imgvCover);
- txtvTitle = findViewById(R.id.txtvTitle);
- TextView txtvAuthorHeader = findViewById(R.id.txtvAuthor);
- ImageView imgvBackground = findViewById(R.id.imgvBackground);
- findViewById(R.id.butShowInfo).setVisibility(View.INVISIBLE);
- findViewById(R.id.butShowSettings).setVisibility(View.INVISIBLE);
- // https://github.com/bumptech/glide/issues/529
- imgvBackground.setColorFilter(new LightingColorFilter(0xff828282, 0x000000));
-
-
- txtvDescription = findViewById(R.id.txtvDescription);
- lblLanguage = findViewById(R.id.lblLanguage);
- txtvLanguage = findViewById(R.id.txtvLanguage);
- lblAuthor = findViewById(R.id.lblAuthor);
- txtvAuthor = findViewById(R.id.txtvDetailsAuthor);
- txtvUrl = findViewById(R.id.txtvUrl);
-
- txtvUrl.setOnClickListener(copyUrlToClipboard);
-
- disposable = Maybe.create((MaybeOnSubscribe<Feed>) emitter -> {
- Feed feed = DBReader.getFeed(feedId);
- if (feed != null) {
- emitter.onSuccess(feed);
- } else {
- emitter.onComplete();
- }
- })
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(result -> {
- feed = result;
- Log.d(TAG, "Language is " + feed.getLanguage());
- Log.d(TAG, "Author is " + feed.getAuthor());
- Log.d(TAG, "URL is " + feed.getDownload_url());
- Glide.with(FeedInfoActivity.this)
- .load(feed.getImageLocation())
- .apply(new RequestOptions()
- .placeholder(R.color.light_gray)
- .error(R.color.light_gray)
- .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
- .fitCenter()
- .dontAnimate())
- .into(imgvCover);
- Glide.with(FeedInfoActivity.this)
- .load(feed.getImageLocation())
- .apply(new RequestOptions()
- .placeholder(R.color.image_readability_tint)
- .error(R.color.image_readability_tint)
- .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
- .transform(new FastBlurTransformation())
- .dontAnimate())
- .into(imgvBackground);
-
- txtvTitle.setText(feed.getTitle());
-
- String description = feed.getDescription();
- if(description != null) {
- if(Feed.TYPE_ATOM1.equals(feed.getType())) {
- HtmlToPlainText formatter = new HtmlToPlainText();
- Document feedDescription = Jsoup.parse(feed.getDescription());
- description = StringUtils.trim(formatter.getPlainText(feedDescription));
- }
- } else {
- description = "";
- }
- txtvDescription.setText(description);
-
- if (!TextUtils.isEmpty(feed.getAuthor())) {
- txtvAuthor.setText(feed.getAuthor());
- txtvAuthorHeader.setText(feed.getAuthor());
- } else {
- lblAuthor.setVisibility(View.GONE);
- txtvAuthor.setVisibility(View.GONE);
- }
- if (!TextUtils.isEmpty(feed.getLanguage())) {
- txtvLanguage.setText(LangUtils.getLanguageString(feed.getLanguage()));
- } else {
- lblLanguage.setVisibility(View.GONE);
- txtvLanguage.setVisibility(View.GONE);
- }
- txtvUrl.setText(feed.getDownload_url() + " {fa-paperclip}");
- Iconify.addIcons(txtvUrl);
-
- supportInvalidateOptionsMenu();
- }, error -> {
- Log.d(TAG, Log.getStackTraceString(error));
- finish();
- }, () -> {
- Log.e(TAG, "Activity was started with invalid arguments");
- finish();
- });
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- if (disposable != null) {
- disposable.dispose();
- }
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- super.onCreateOptionsMenu(menu);
- MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.feedinfo, menu);
- return true;
- }
-
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
- super.onPrepareOptionsMenu(menu);
- menu.findItem(R.id.share_link_item).setVisible(feed != null && feed.getLink() != null);
- menu.findItem(R.id.visit_website_item).setVisible(feed != null && feed.getLink() != null &&
- IntentUtils.isCallable(this, new Intent(Intent.ACTION_VIEW, Uri.parse(feed.getLink()))));
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- finish();
- return true;
- default:
- try {
- return FeedMenuHandler.onOptionsItemClicked(this, item, feed);
- } catch (DownloadRequestException e) {
- e.printStackTrace();
- DownloadRequestErrorDialogCreator.newRequestErrorDialog(this,
- e.getMessage());
- }
- return super.onOptionsItemSelected(item);
- }
- }
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/FeedSettingsActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/FeedSettingsActivity.java
deleted file mode 100644
index fbd19f88a..000000000
--- a/app/src/main/java/de/danoeh/antennapod/activity/FeedSettingsActivity.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package de.danoeh.antennapod.activity;
-
-import android.arch.lifecycle.ViewModelProviders;
-import android.graphics.LightingColorFilter;
-import android.os.Bundle;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentTransaction;
-import android.support.v7.app.AppCompatActivity;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-import com.bumptech.glide.Glide;
-import com.bumptech.glide.request.RequestOptions;
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.feed.Feed;
-import de.danoeh.antennapod.core.glide.ApGlideSettings;
-import de.danoeh.antennapod.core.glide.FastBlurTransformation;
-import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.fragment.FeedSettingsFragment;
-import de.danoeh.antennapod.viewmodel.FeedSettingsViewModel;
-import io.reactivex.android.schedulers.AndroidSchedulers;
-import io.reactivex.disposables.Disposable;
-import io.reactivex.schedulers.Schedulers;
-
-/**
- * Displays information about a feed.
- */
-public class FeedSettingsActivity extends AppCompatActivity {
- public static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
- private static final String TAG = "FeedSettingsActivity";
- private Feed feed;
- private Disposable disposable;
- private ImageView imgvCover;
- private TextView txtvTitle;
- private ImageView imgvBackground;
- private TextView txtvAuthorHeader;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- setTheme(UserPreferences.getTheme());
- super.onCreate(savedInstanceState);
- setContentView(R.layout.feedsettings);
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
-
- imgvCover = findViewById(R.id.imgvCover);
- txtvTitle = findViewById(R.id.txtvTitle);
- txtvAuthorHeader = findViewById(R.id.txtvAuthor);
- imgvBackground = findViewById(R.id.imgvBackground);
- findViewById(R.id.butShowInfo).setVisibility(View.INVISIBLE);
- findViewById(R.id.butShowSettings).setVisibility(View.INVISIBLE);
- // https://github.com/bumptech/glide/issues/529
- imgvBackground.setColorFilter(new LightingColorFilter(0xff828282, 0x000000));
-
- long feedId = getIntent().getLongExtra(EXTRA_FEED_ID, -1);
- disposable = ViewModelProviders.of(this).get(FeedSettingsViewModel.class).getFeed(feedId)
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(result -> {
- feed = result;
- showFragment();
- showHeader();
- }, error -> {
- Log.d(TAG, Log.getStackTraceString(error));
- finish();
- }, () -> {
- Log.e(TAG, "Activity was started with invalid arguments");
- finish();
- });
- }
-
- private void showFragment() {
- FeedSettingsFragment fragment = new FeedSettingsFragment();
- fragment.setArguments(getIntent().getExtras());
-
- FragmentManager fragmentManager = getSupportFragmentManager();
- FragmentTransaction fragmentTransaction =
- fragmentManager.beginTransaction();
- fragmentTransaction.replace(R.id.settings_fragment_container, fragment);
- fragmentTransaction.commit();
- }
-
- private void showHeader() {
- txtvTitle.setText(feed.getTitle());
-
- if (!TextUtils.isEmpty(feed.getAuthor())) {
- txtvAuthorHeader.setText(feed.getAuthor());
- }
-
- Glide.with(FeedSettingsActivity.this)
- .load(feed.getImageLocation())
- .apply(new RequestOptions()
- .placeholder(R.color.light_gray)
- .error(R.color.light_gray)
- .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
- .fitCenter()
- .dontAnimate())
- .into(imgvCover);
- Glide.with(FeedSettingsActivity.this)
- .load(feed.getImageLocation())
- .apply(new RequestOptions()
- .placeholder(R.color.image_readability_tint)
- .error(R.color.image_readability_tint)
- .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
- .transform(new FastBlurTransformation())
- .dontAnimate())
- .into(imgvBackground);
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- if (disposable != null) {
- disposable.dispose();
- }
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- finish();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
- }
-}
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 b028f7983..b778fe77e 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
@@ -69,6 +69,7 @@ import de.danoeh.antennapod.fragment.FeedItemlistFragment;
import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
import de.danoeh.antennapod.fragment.QueueFragment;
import de.danoeh.antennapod.fragment.SubscriptionFragment;
+import de.danoeh.antennapod.fragment.TransitionEffect;
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
import de.danoeh.antennapod.preferences.PreferenceUpgrader;
import io.reactivex.Observable;
@@ -377,15 +378,34 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
}
}
- public void loadChildFragment(Fragment fragment) {
+ public void loadChildFragment(Fragment fragment, TransitionEffect transition) {
Validate.notNull(fragment);
- FragmentManager fm = getSupportFragmentManager();
- fm.beginTransaction()
- .replace(R.id.main_view, fragment, "main")
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+
+ switch (transition) {
+ case FADE:
+ transaction.setCustomAnimations(R.anim.fade_in, R.anim.fade_out);
+ break;
+ case FLIP:
+ transaction.setCustomAnimations(
+ R.anim.card_flip_left_in,
+ R.anim.card_flip_left_out,
+ R.anim.card_flip_right_in,
+ R.anim.card_flip_right_out);
+ break;
+ }
+
+ transaction
+ .hide(getSupportFragmentManager().findFragmentByTag("main"))
+ .add(R.id.main_view, fragment, "main")
.addToBackStack(null)
.commit();
}
+ public void loadChildFragment(Fragment fragment) {
+ loadChildFragment(fragment, TransitionEffect.NONE);
+ }
+
public void dismissChildFragment() {
getSupportFragmentManager().popBackStack();
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java
new file mode 100644
index 000000000..a1df6c428
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java
@@ -0,0 +1,234 @@
+package de.danoeh.antennapod.fragment;
+
+import android.content.ClipData;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.LightingColorFilter;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.request.RequestOptions;
+import com.joanzapata.iconify.Iconify;
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.activity.MainActivity;
+import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
+import de.danoeh.antennapod.core.feed.Feed;
+import de.danoeh.antennapod.core.glide.ApGlideSettings;
+import de.danoeh.antennapod.core.glide.FastBlurTransformation;
+import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.DownloadRequestException;
+import de.danoeh.antennapod.core.util.IntentUtils;
+import de.danoeh.antennapod.core.util.LangUtils;
+import de.danoeh.antennapod.core.util.syndication.HtmlToPlainText;
+import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
+import io.reactivex.Maybe;
+import io.reactivex.MaybeOnSubscribe;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.disposables.Disposable;
+import io.reactivex.schedulers.Schedulers;
+import org.apache.commons.lang3.StringUtils;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+
+/**
+ * Displays information about a feed.
+ */
+public class FeedInfoFragment extends Fragment {
+
+ private static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
+ private static final String TAG = "FeedInfoActivity";
+
+ private Feed feed;
+ private Disposable disposable;
+ private ImageView imgvCover;
+ private TextView txtvTitle;
+ private TextView txtvDescription;
+ private TextView lblLanguage;
+ private TextView txtvLanguage;
+ private TextView lblAuthor;
+ private TextView txtvAuthor;
+ private TextView txtvUrl;
+ private TextView txtvAuthorHeader;
+ private ImageView imgvBackground;
+
+ public static FeedInfoFragment newInstance(Feed feed) {
+ FeedInfoFragment fragment = new FeedInfoFragment();
+ Bundle arguments = new Bundle();
+ arguments.putLong(EXTRA_FEED_ID, feed.getId());
+ fragment.setArguments(arguments);
+ return fragment;
+ }
+
+ private final View.OnClickListener copyUrlToClipboard = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if(feed != null && feed.getDownload_url() != null) {
+ String url = feed.getDownload_url();
+ ClipData clipData = ClipData.newPlainText(url, url);
+ android.content.ClipboardManager cm = (android.content.ClipboardManager) getContext()
+ .getSystemService(Context.CLIPBOARD_SERVICE);
+ cm.setPrimaryClip(clipData);
+ Toast t = Toast.makeText(getContext(), R.string.copied_url_msg, Toast.LENGTH_SHORT);
+ t.show();
+ }
+ }
+ };
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ ((MainActivity)getActivity()).getSupportActionBar().setTitle(R.string.feed_info_label);
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ View root = inflater.inflate(R.layout.feedinfo, null);
+ setHasOptionsMenu(true);
+
+ imgvCover = root.findViewById(R.id.imgvCover);
+ txtvTitle = root.findViewById(R.id.txtvTitle);
+ txtvAuthorHeader = root.findViewById(R.id.txtvAuthor);
+ imgvBackground = root.findViewById(R.id.imgvBackground);
+ root.findViewById(R.id.butShowInfo).setVisibility(View.INVISIBLE);
+ root.findViewById(R.id.butShowSettings).setVisibility(View.INVISIBLE);
+ // https://github.com/bumptech/glide/issues/529
+ imgvBackground.setColorFilter(new LightingColorFilter(0xff828282, 0x000000));
+
+
+ txtvDescription = root.findViewById(R.id.txtvDescription);
+ lblLanguage = root.findViewById(R.id.lblLanguage);
+ txtvLanguage = root.findViewById(R.id.txtvLanguage);
+ lblAuthor = root.findViewById(R.id.lblAuthor);
+ txtvAuthor = root.findViewById(R.id.txtvDetailsAuthor);
+ txtvUrl = root.findViewById(R.id.txtvUrl);
+
+ txtvUrl.setOnClickListener(copyUrlToClipboard);
+ postponeEnterTransition();
+ return root;
+ }
+
+ @Override
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+ long feedId = getArguments().getLong(EXTRA_FEED_ID);
+ disposable = Maybe.create((MaybeOnSubscribe<Feed>) emitter -> {
+ Feed feed = DBReader.getFeed(feedId);
+ if (feed != null) {
+ emitter.onSuccess(feed);
+ } else {
+ emitter.onComplete();
+ }
+ })
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(result -> {
+ feed = result;
+ showFeed();
+ }, error -> Log.d(TAG, Log.getStackTraceString(error)),
+ this::startPostponedEnterTransition);
+ }
+
+ private void showFeed() {
+ Log.d(TAG, "Language is " + feed.getLanguage());
+ Log.d(TAG, "Author is " + feed.getAuthor());
+ Log.d(TAG, "URL is " + feed.getDownload_url());
+ Glide.with(getContext())
+ .load(feed.getImageLocation())
+ .apply(new RequestOptions()
+ .placeholder(R.color.light_gray)
+ .error(R.color.light_gray)
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .fitCenter()
+ .dontAnimate())
+ .into(imgvCover);
+ Glide.with(getContext())
+ .load(feed.getImageLocation())
+ .apply(new RequestOptions()
+ .placeholder(R.color.image_readability_tint)
+ .error(R.color.image_readability_tint)
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .transform(new FastBlurTransformation())
+ .dontAnimate())
+ .into(imgvBackground);
+
+ txtvTitle.setText(feed.getTitle());
+
+ String description = feed.getDescription();
+ if(description != null) {
+ if(Feed.TYPE_ATOM1.equals(feed.getType())) {
+ HtmlToPlainText formatter = new HtmlToPlainText();
+ Document feedDescription = Jsoup.parse(feed.getDescription());
+ description = StringUtils.trim(formatter.getPlainText(feedDescription));
+ }
+ } else {
+ description = "";
+ }
+ txtvDescription.setText(description);
+
+ if (!TextUtils.isEmpty(feed.getAuthor())) {
+ txtvAuthor.setText(feed.getAuthor());
+ txtvAuthorHeader.setText(feed.getAuthor());
+ } else {
+ lblAuthor.setVisibility(View.GONE);
+ txtvAuthor.setVisibility(View.GONE);
+ }
+ if (!TextUtils.isEmpty(feed.getLanguage())) {
+ txtvLanguage.setText(LangUtils.getLanguageString(feed.getLanguage()));
+ } else {
+ lblLanguage.setVisibility(View.GONE);
+ txtvLanguage.setVisibility(View.GONE);
+ }
+ txtvUrl.setText(feed.getDownload_url() + " {fa-paperclip}");
+ Iconify.addIcons(txtvUrl);
+
+ getActivity().invalidateOptionsMenu();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ if (disposable != null) {
+ disposable.dispose();
+ }
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ super.onCreateOptionsMenu(menu, inflater);
+ inflater.inflate(R.menu.feedinfo, menu);
+ }
+
+ @Override
+ public void onPrepareOptionsMenu(Menu menu) {
+ super.onPrepareOptionsMenu(menu);
+ menu.findItem(R.id.share_link_item).setVisible(feed != null && feed.getLink() != null);
+ menu.findItem(R.id.visit_website_item).setVisible(feed != null && feed.getLink() != null &&
+ IntentUtils.isCallable(getContext(), new Intent(Intent.ACTION_VIEW, Uri.parse(feed.getLink()))));
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ boolean handled = false;
+ try {
+ handled = FeedMenuHandler.onOptionsItemClicked(getContext(), item, feed);
+ } catch (DownloadRequestException e) {
+ e.printStackTrace();
+ DownloadRequestErrorDialogCreator.newRequestErrorDialog(getContext(), e.getMessage());
+ }
+ return handled || super.onOptionsItemSelected(item);
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java
index 8fe0883b2..745404aeb 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java
@@ -38,8 +38,6 @@ import org.greenrobot.eventbus.ThreadMode;
import java.util.List;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.FeedInfoActivity;
-import de.danoeh.antennapod.activity.FeedSettingsActivity;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.FeedItemlistAdapter;
import de.danoeh.antennapod.core.asynctask.FeedRemover;
@@ -141,37 +139,33 @@ public class FeedItemlistFragment extends ListFragment {
}
@Override
- public void onStart() {
- super.onStart();
+ public void onHiddenChanged(boolean hidden) {
+ super.onHiddenChanged(hidden);
+ if (!hidden && getActivity() != null) {
+ ((MainActivity) getActivity()).getSupportActionBar().setTitle("");
+ }
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ registerForContextMenu(getListView());
+
EventDistributor.getInstance().register(contentUpdate);
EventBus.getDefault().register(this);
loadItems();
}
@Override
- public void onResume() {
- super.onResume();
- ((MainActivity)getActivity()).getSupportActionBar().setTitle("");
- updateProgressBarVisibility();
- }
+ public void onDestroyView() {
+ super.onDestroyView();
- @Override
- public void onStop() {
- super.onStop();
EventDistributor.getInstance().unregister(contentUpdate);
EventBus.getDefault().unregister(this);
- if(disposable != null) {
+ if (disposable != null) {
disposable.dispose();
}
- }
-
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- resetViewState();
- }
-
- private void resetViewState() {
adapter = null;
listFooter = null;
}
@@ -345,13 +339,6 @@ public class FeedItemlistFragment extends ListFragment {
}
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
-
- registerForContextMenu(getListView());
- }
-
- @Override
public void onListItemClick(ListView l, View v, int position, long id) {
if(adapter == null) {
return;
@@ -429,8 +416,9 @@ public class FeedItemlistFragment extends ListFragment {
}
- private void onFragmentLoaded() {
- if(!isVisible()) {
+ private void displayList() {
+ if (getView() == null) {
+ Log.e(TAG, "Required root view is not yet created. Stop binding data to UI.");
return;
}
if (adapter == null) {
@@ -514,10 +502,8 @@ public class FeedItemlistFragment extends ListFragment {
imgvCover.setOnClickListener(v -> showFeedInfo());
butShowSettings.setOnClickListener(v -> {
if (feed != null) {
- Intent startIntent = new Intent(getActivity(), FeedSettingsActivity.class);
- startIntent.putExtra(FeedSettingsActivity.EXTRA_FEED_ID,
- feed.getId());
- startActivity(startIntent);
+ FeedSettingsFragment fragment = FeedSettingsFragment.newInstance(feed);
+ ((MainActivity) getActivity()).loadChildFragment(fragment, TransitionEffect.FLIP);
}
});
headerCreated = true;
@@ -525,10 +511,8 @@ public class FeedItemlistFragment extends ListFragment {
private void showFeedInfo() {
if (feed != null) {
- Intent startIntent = new Intent(getActivity(), FeedInfoActivity.class);
- startIntent.putExtra(FeedInfoActivity.EXTRA_FEED_ID,
- feed.getId());
- startActivity(startIntent);
+ FeedInfoFragment fragment = FeedInfoFragment.newInstance(feed);
+ ((MainActivity) getActivity()).loadChildFragment(fragment, TransitionEffect.FLIP);
}
}
@@ -634,7 +618,7 @@ public class FeedItemlistFragment extends ListFragment {
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
feed = result.orElse(null);
- onFragmentLoaded();
+ displayList();
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java
index 4fb3d90f5..f9564336d 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java
@@ -1,39 +1,66 @@
package de.danoeh.antennapod.fragment;
-import android.arch.lifecycle.ViewModelProviders;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.PreferenceFragmentCompat;
+import android.util.Log;
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedFilter;
import de.danoeh.antennapod.core.feed.FeedPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
+import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.dialog.AuthenticationDialog;
import de.danoeh.antennapod.dialog.EpisodeFilterDialog;
-import de.danoeh.antennapod.viewmodel.FeedSettingsViewModel;
-
-import static de.danoeh.antennapod.activity.FeedSettingsActivity.EXTRA_FEED_ID;
+import io.reactivex.Maybe;
+import io.reactivex.MaybeOnSubscribe;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.disposables.Disposable;
+import io.reactivex.schedulers.Schedulers;
public class FeedSettingsFragment extends PreferenceFragmentCompat {
private static final CharSequence PREF_EPISODE_FILTER = "episodeFilter";
+ private static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
+ private static final String TAG = "FeedSettingsFragment";
+
private Feed feed;
+ private Disposable disposable;
private FeedPreferences feedPreferences;
+ public static FeedSettingsFragment newInstance(Feed feed) {
+ FeedSettingsFragment fragment = new FeedSettingsFragment();
+ Bundle arguments = new Bundle();
+ arguments.putLong(EXTRA_FEED_ID, feed.getId());
+ fragment.setArguments(arguments);
+ return fragment;
+ }
+
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.feed_settings);
+ postponeEnterTransition();
long feedId = getArguments().getLong(EXTRA_FEED_ID);
- ViewModelProviders.of(getActivity()).get(FeedSettingsViewModel.class).getFeed(feedId)
+ disposable = Maybe.create((MaybeOnSubscribe<Feed>) emitter -> {
+ Feed feed = DBReader.getFeed(feedId);
+ if (feed != null) {
+ emitter.onSuccess(feed);
+ } else {
+ emitter.onComplete();
+ }
+ })
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
feed = result;
feedPreferences = feed.getPreferences();
+ ((MainActivity) getActivity()).getSupportActionBar().setSubtitle(feed.getTitle());
setupAutoDownloadPreference();
setupKeepUpdatedPreference();
@@ -43,7 +70,31 @@ public class FeedSettingsFragment extends PreferenceFragmentCompat {
updateAutoDeleteSummary();
updateAutoDownloadEnabled();
- }).dispose();
+ }, error -> Log.d(TAG, Log.getStackTraceString(error)),
+ this::startPostponedEnterTransition);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ ((MainActivity) getActivity()).getSupportActionBar().setTitle(R.string.feed_settings_label);
+ if (feed != null) {
+ ((MainActivity) getActivity()).getSupportActionBar().setSubtitle(feed.getTitle());
+ }
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ ((MainActivity) getActivity()).getSupportActionBar().setSubtitle(null);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ if (disposable != null) {
+ disposable.dispose();
+ }
}
private void setupEpisodeFilterPreference() {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/TransitionEffect.java b/app/src/main/java/de/danoeh/antennapod/fragment/TransitionEffect.java
new file mode 100644
index 000000000..461fa9da3
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/TransitionEffect.java
@@ -0,0 +1,5 @@
+package de.danoeh.antennapod.fragment;
+
+public enum TransitionEffect {
+ NONE, FLIP, FADE
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/viewmodel/FeedSettingsViewModel.java b/app/src/main/java/de/danoeh/antennapod/viewmodel/FeedSettingsViewModel.java
deleted file mode 100644
index fe11a645c..000000000
--- a/app/src/main/java/de/danoeh/antennapod/viewmodel/FeedSettingsViewModel.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package de.danoeh.antennapod.viewmodel;
-
-import android.arch.lifecycle.ViewModel;
-import de.danoeh.antennapod.core.feed.Feed;
-import de.danoeh.antennapod.core.storage.DBReader;
-import io.reactivex.Maybe;
-
-public class FeedSettingsViewModel extends ViewModel {
- private Feed feed;
-
- public Maybe<Feed> getFeed(long feedId) {
- if (feed == null) {
- return loadFeed(feedId);
- } else {
- return Maybe.just(feed);
- }
- }
-
- private Maybe<Feed> loadFeed(long feedId) {
- return Maybe.create(emitter -> {
- Feed feed = DBReader.getFeed(feedId);
- if (feed != null) {
- this.feed = feed;
- emitter.onSuccess(feed);
- } else {
- emitter.onComplete();
- }
- });
- }
-}
diff --git a/app/src/main/res/anim/card_flip_left_in.xml b/app/src/main/res/anim/card_flip_left_in.xml
new file mode 100644
index 000000000..0ffc85aec
--- /dev/null
+++ b/app/src/main/res/anim/card_flip_left_in.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Before rotating, immediately set the alpha to 0. -->
+ <objectAnimator
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:propertyName="alpha"
+ android:duration="0" />
+
+ <!-- Rotate. -->
+ <objectAnimator
+ android:valueFrom="-180"
+ android:valueTo="0"
+ android:propertyName="rotationY"
+ android:interpolator="@android:interpolator/accelerate_decelerate"
+ android:duration="@integer/card_flip_time_full" />
+
+ <!-- Half-way through the rotation (see startOffset), set the alpha to 1. -->
+ <objectAnimator
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:propertyName="alpha"
+ android:startOffset="@integer/card_flip_time_half"
+ android:duration="1" />
+</set> \ No newline at end of file
diff --git a/app/src/main/res/anim/card_flip_left_out.xml b/app/src/main/res/anim/card_flip_left_out.xml
new file mode 100644
index 000000000..817f0d3fc
--- /dev/null
+++ b/app/src/main/res/anim/card_flip_left_out.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Rotate. -->
+ <objectAnimator
+ android:valueFrom="0"
+ android:valueTo="180"
+ android:propertyName="rotationY"
+ android:interpolator="@android:interpolator/accelerate_decelerate"
+ android:duration="@integer/card_flip_time_full" />
+
+ <!-- Half-way through the rotation (see startOffset), set the alpha to 0. -->
+ <objectAnimator
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:propertyName="alpha"
+ android:startOffset="@integer/card_flip_time_half"
+ android:duration="1" />
+</set> \ No newline at end of file
diff --git a/app/src/main/res/anim/card_flip_right_in.xml b/app/src/main/res/anim/card_flip_right_in.xml
new file mode 100644
index 000000000..31ff1dde5
--- /dev/null
+++ b/app/src/main/res/anim/card_flip_right_in.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Before rotating, immediately set the alpha to 0. -->
+ <objectAnimator
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:propertyName="alpha"
+ android:duration="0" />
+
+ <!-- Rotate. -->
+ <objectAnimator
+ android:valueFrom="180"
+ android:valueTo="0"
+ android:propertyName="rotationY"
+ android:interpolator="@android:interpolator/accelerate_decelerate"
+ android:duration="@integer/card_flip_time_full" />
+
+ <!-- Half-way through the rotation (see startOffset), set the alpha to 1. -->
+ <objectAnimator
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:propertyName="alpha"
+ android:startOffset="@integer/card_flip_time_half"
+ android:duration="1" />
+</set> \ No newline at end of file
diff --git a/app/src/main/res/anim/card_flip_right_out.xml b/app/src/main/res/anim/card_flip_right_out.xml
new file mode 100644
index 000000000..b57113fea
--- /dev/null
+++ b/app/src/main/res/anim/card_flip_right_out.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Rotate. -->
+ <objectAnimator
+ android:valueFrom="0"
+ android:valueTo="-180"
+ android:propertyName="rotationY"
+ android:interpolator="@android:interpolator/accelerate_decelerate"
+ android:duration="@integer/card_flip_time_full" />
+
+ <!-- Half-way through the rotation (see startOffset), set the alpha to 0. -->
+ <objectAnimator
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:propertyName="alpha"
+ android:startOffset="@integer/card_flip_time_half"
+ android:duration="1" />
+</set> \ No newline at end of file
diff --git a/app/src/main/res/values/integers.xml b/app/src/main/res/values/integers.xml
new file mode 100644
index 000000000..8c444ee8b
--- /dev/null
+++ b/app/src/main/res/values/integers.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <integer name="card_flip_time_full">400</integer>
+ <integer name="card_flip_time_half">200</integer>
+</resources> \ No newline at end of file