diff --git a/app/build.gradle b/app/build.gradle index eb4b25de8..2fe94d576 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,7 +14,7 @@ dependencies { compile "com.android.support:gridlayout-v7:$supportVersion" compile "com.android.support:cardview-v7:$supportVersion" compile "com.android.support:design:$supportVersion" - compile "com.android.support:recyclerview-v7:22.2.+" + compile "com.android.support:recyclerview-v7:$supportVersion" compile "org.apache.commons:commons-lang3:$commonslangVersion" compile("org.shredzone.flattr4j:flattr4j-core:$flattr4jVersion") { exclude group: "org.json", module: "json" @@ -31,9 +31,12 @@ dependencies { compile "io.reactivex:rxjava:$rxJavaVersion" // And ProGuard rules for RxJava! compile "com.artemzin.rxjava:proguard-rules:$rxJavaRulesVersion" - compile "com.joanzapata.iconify:android-iconify-fontawesome:2.1.0" - compile "com.afollestad:material-dialogs:0.7.8.1" - compile "com.yqritc:recyclerview-flexibledivider:1.2.6" + compile "com.joanzapata.iconify:android-iconify-fontawesome:$iconifyFontawesomeVersion" + compile "com.joanzapata.iconify:android-iconify-material:$iconifyFontawesomeVersion" + compile("com.github.afollestad.material-dialogs:commons:$materialDialogsVersion") { + transitive = true + } + compile "com.yqritc:recyclerview-flexibledivider:$recyclerviewFlexibledividerVersion" compile "com.github.AntennaPod:AntennaPod-AudioPlayer:$audioPlayerVersion" diff --git a/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java b/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java index 4dae53a15..e456f3891 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java @@ -51,6 +51,7 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2 hidden = UserPreferences.getHiddenDrawerItems(); assertEquals(titles.length, hidden.size()); - for(String tag : MainActivity.NAV_DRAWER_TAGS) { + for (String tag : MainActivity.NAV_DRAWER_TAGS) { assertTrue(hidden.contains(tag)); } } diff --git a/app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java b/app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java index c43757546..d65925703 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java @@ -1,7 +1,6 @@ package de.test.antennapod.ui; import android.annotation.TargetApi; -import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; @@ -10,7 +9,6 @@ import android.preference.PreferenceManager; import android.test.ActivityInstrumentationTestCase2; import android.test.FlakyTest; import android.view.View; -import android.widget.ImageButton; import android.widget.ListView; import com.robotium.solo.Solo; @@ -21,15 +19,12 @@ import java.util.List; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.core.feed.FeedItem; -import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.core.service.playback.PlayerStatus; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.PodDBAdapter; -import de.danoeh.antennapod.core.util.playback.Playable; -import de.danoeh.antennapod.core.util.playback.PlaybackController; /** * test cases for starting and ending playback from the MainActivity and AudioPlayerActivity @@ -90,7 +85,7 @@ public class PlaybackSonicTest extends ActivityInstrumentationTestCase2 super.tearDown(); } - private void openNavDrawer() { - solo.clickOnScreen(50, 50); + solo.clickOnImageButton(0); + getInstrumentation().waitForIdleSync(); } private void setContinuousPlaybackPreference(boolean value) { diff --git a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtilsTest.java b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtilsTest.java index 6c5a350de..53fd7d7fd 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtilsTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtilsTest.java @@ -1,15 +1,15 @@ package de.test.antennapod.ui; import android.test.InstrumentationTestCase; -import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.feed.FeedItem; -import org.apache.http.HttpStatus; import java.io.File; import java.net.HttpURLConnection; import java.net.URL; import java.util.List; +import de.danoeh.antennapod.core.feed.Feed; +import de.danoeh.antennapod.core.feed.FeedItem; + /** * Test for the UITestUtils. Makes sure that all URLs are reachable and that the class does not cause any crashes. */ @@ -55,7 +55,7 @@ public class UITestUtilsTest extends InstrumentationTestCase { conn.setRequestMethod("GET"); conn.connect(); int rc = conn.getResponseCode(); - assertEquals(HttpStatus.SC_OK, rc); + assertEquals(HttpURLConnection.HTTP_OK, rc); conn.disconnect(); } diff --git a/app/src/androidTest/java/de/test/antennapod/util/service/download/NanoHTTPD.java b/app/src/androidTest/java/de/test/antennapod/util/service/download/NanoHTTPD.java index 4a5818479..28ff6694e 100644 --- a/app/src/androidTest/java/de/test/antennapod/util/service/download/NanoHTTPD.java +++ b/app/src/androidTest/java/de/test/antennapod/util/service/download/NanoHTTPD.java @@ -1,6 +1,21 @@ package de.test.antennapod.util.service.download; -import java.io.*; +import android.support.v4.util.ArrayMap; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.Closeable; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.io.PushbackInputStream; +import java.io.RandomAccessFile; +import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; @@ -14,7 +29,6 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -281,7 +295,7 @@ public abstract class NanoHTTPD { * @return HTTP response, see class Response for details */ public Response serve(IHTTPSession session) { - Map files = new HashMap(); + Map files = new ArrayMap<>(); Method method = session.getMethod(); if (Method.PUT.equals(method) || Method.POST.equals(method)) { try { @@ -334,7 +348,7 @@ public abstract class NanoHTTPD { * @return a map of String (parameter name) to List<String> (a list of the values supplied). */ protected Map> decodeParameters(String queryString) { - Map> parms = new HashMap>(); + Map> parms = new ArrayMap>(); if (queryString != null) { StringTokenizer st = new StringTokenizer(queryString, "&"); while (st.hasMoreTokens()) { @@ -549,7 +563,7 @@ public abstract class NanoHTTPD { /** * Headers for the HTTP response. Use addHeader() to add lines. */ - private Map header = new HashMap(); + private Map header = new ArrayMap(); /** * The request method that spawned this response. */ @@ -851,7 +865,7 @@ public abstract class NanoHTTPD { this.inputStream = new PushbackInputStream(inputStream, BUFSIZE); this.outputStream = outputStream; String remoteIp = inetAddress.isLoopbackAddress() || inetAddress.isAnyLocalAddress() ? "127.0.0.1" : inetAddress.getHostAddress().toString(); - headers = new HashMap(); + headers = new ArrayMap(); headers.put("remote-addr", remoteIp); headers.put("http-client-ip", remoteIp); @@ -895,16 +909,16 @@ public abstract class NanoHTTPD { inputStream.unread(buf, splitbyte, rlen - splitbyte); } - parms = new HashMap(); + parms = new ArrayMap(); if(null == headers) { - headers = new HashMap(); + headers = new ArrayMap(); } // Create a BufferedReader for parsing the header. BufferedReader hin = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(buf, 0, rlen))); // Decode the header into parms and header java properties - Map pre = new HashMap(); + Map pre = new ArrayMap(); decodeHeader(hin, pre, parms, headers); method = Method.lookup(pre.get("method")); @@ -1102,7 +1116,7 @@ public abstract class NanoHTTPD { throw new ResponseException(Response.Status.BAD_REQUEST, "BAD REQUEST: Content type is multipart/form-data but next chunk does not start with boundary. Usage: GET /example/file.html"); } boundarycount++; - Map item = new HashMap(); + Map item = new ArrayMap(); mpline = in.readLine(); while (mpline != null && mpline.trim().length() > 0) { int p = mpline.indexOf(':'); @@ -1117,7 +1131,7 @@ public abstract class NanoHTTPD { throw new ResponseException(Response.Status.BAD_REQUEST, "BAD REQUEST: Content type is multipart/form-data but no content-disposition info found. Usage: GET /example/file.html"); } StringTokenizer st = new StringTokenizer(contentDisposition, ";"); - Map disposition = new HashMap(); + Map disposition = new ArrayMap(); while (st.hasMoreTokens()) { String token = st.nextToken().trim(); int p = token.indexOf('='); @@ -1352,7 +1366,7 @@ public abstract class NanoHTTPD { * @author LordFokas */ public class CookieHandler implements Iterable { - private HashMap cookies = new HashMap(); + private ArrayMap cookies = new ArrayMap(); private ArrayList queue = new ArrayList(); public CookieHandler(Map httpHeaders) { diff --git a/app/src/main/java/de/danoeh/antennapod/PodcastApp.java b/app/src/main/java/de/danoeh/antennapod/PodcastApp.java index 835f43f40..c1d4bc4fd 100644 --- a/app/src/main/java/de/danoeh/antennapod/PodcastApp.java +++ b/app/src/main/java/de/danoeh/antennapod/PodcastApp.java @@ -6,6 +6,7 @@ import android.os.StrictMode; import com.joanzapata.iconify.Iconify; import com.joanzapata.iconify.fonts.FontAwesomeModule; +import com.joanzapata.iconify.fonts.MaterialModule; import de.danoeh.antennapod.core.feed.EventDistributor; import de.danoeh.antennapod.core.preferences.PlaybackPreferences; @@ -62,6 +63,7 @@ public class PodcastApp extends Application { NetworkUtils.init(this); EventDistributor.getInstance(); Iconify.with(new FontAwesomeModule()); + Iconify.with(new MaterialModule()); SPAUtil.sendSPAppsQueryFeedsIntent(this); } 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 017c28dbf..17cd5ace3 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java @@ -15,12 +15,12 @@ import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v4.widget.DrawerLayout; -import android.support.v7.app.ActionBar; -import android.support.v7.app.ActionBarActivity; import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.util.Log; +import android.util.TypedValue; import android.view.ContextMenu; import android.view.MenuInflater; import android.view.MenuItem; @@ -71,7 +71,7 @@ import rx.schedulers.Schedulers; /** * The activity that is shown when the user launches the app. */ -public class MainActivity extends ActionBarActivity implements NavDrawerActivity { +public class MainActivity extends AppCompatActivity implements NavDrawerActivity { private static final String TAG = "MainActivity"; @@ -125,7 +125,13 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); - getSupportActionBar().setElevation(3.0f); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + findViewById(R.id.shadow).setVisibility(View.GONE); + int elevation = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, + getResources().getDisplayMetrics()); + getSupportActionBar().setElevation(elevation); + } currentTitle = getTitle(); @@ -252,10 +258,6 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity builder.create().show(); } - public ActionBar getMainActivtyActionBar() { - return getSupportActionBar(); - } - public boolean isDrawerOpen() { return drawerLayout != null && navDrawer != null && drawerLayout.isDrawerOpen(navDrawer); } @@ -363,10 +365,6 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity getSupportFragmentManager().popBackStack(); } - public Toolbar getToolbar() { - return toolbar; - } - private int getSelectedNavListIndex() { String currentFragment = getLastNavFragment(); if(currentFragment == null) { diff --git a/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java index 7f975b3c8..b02e82f0b 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java @@ -39,7 +39,7 @@ public class StorageErrorActivity extends ActionBarActivity { @Override protected void onResume() { super.onResume(); - if (StorageUtils.storageAvailable(this)) { + if (StorageUtils.storageAvailable()) { leaveErrorState(); } else { registerReceiver(mediaUpdate, new IntentFilter( diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java index e867540e4..16909cbb3 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java @@ -5,6 +5,7 @@ import android.graphics.Color; import android.os.Bundle; import android.support.v4.app.ActivityCompat; import android.support.v4.app.Fragment; +import android.support.v4.util.ArrayMap; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -22,7 +23,6 @@ import com.joanzapata.iconify.fonts.FontAwesomeIcons; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -58,7 +58,7 @@ public class EpisodesApplyActionFragment extends Fragment { public EpisodesApplyActionFragment() { this.episodes = new ArrayList<>(); - this.idMap = new HashMap<>(); + this.idMap = new ArrayMap<>(); } public void setEpisodes(List episodes) { diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java index f6c80aa7c..d979dc382 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java @@ -45,7 +45,7 @@ public class AddFeedFragment extends Fragment { Button butSearchITunes = (Button) root.findViewById(R.id.butSearchItunes); final MainActivity activity = (MainActivity) getActivity(); - activity.getMainActivtyActionBar().setTitle(R.string.add_feed_label); + activity.getSupportActionBar().setTitle(R.string.add_feed_label); butSearchITunes.setOnClickListener(new View.OnClickListener() { @Override diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java index 091f4c843..9ccb0fbe3 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java @@ -10,6 +10,7 @@ import android.support.v4.view.MenuItemCompat; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.SearchView; +import android.support.v7.widget.SimpleItemAnimator; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; @@ -303,7 +304,10 @@ public class AllEpisodesFragment extends Fragment { View root = inflater.inflate(fragmentResource, container, false); recyclerView = (RecyclerView) root.findViewById(android.R.id.list); - recyclerView.getItemAnimator().setSupportsChangeAnimations(false); + RecyclerView.ItemAnimator animator = recyclerView.getItemAnimator(); + if (animator instanceof SimpleItemAnimator) { + ((SimpleItemAnimator) animator).setSupportsChangeAnimations(false); + } layoutManager = new LinearLayoutManager(getActivity()); recyclerView.setLayoutManager(layoutManager); recyclerView.setHasFixedSize(true); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java index 10d56d5cf..58cd6c40a 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java @@ -4,35 +4,33 @@ import android.annotation.TargetApi; import android.content.ClipData; import android.content.Context; import android.content.Intent; -import android.content.res.TypedArray; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v4.util.Pair; -import android.support.v7.widget.PopupMenu; -import android.support.v7.widget.Toolbar; import android.text.TextUtils; import android.text.format.DateUtils; import android.util.Log; import android.view.ContextMenu; 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.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; -import android.widget.Button; -import android.widget.ImageButton; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import com.bumptech.glide.Glide; +import com.joanzapata.iconify.Iconify; +import com.joanzapata.iconify.widget.IconButton; import org.apache.commons.lang3.ArrayUtils; @@ -101,7 +99,6 @@ public class ItemFragment extends Fragment { private List downloaderList; private ViewGroup root; - private View header; private WebView webvDescription; private TextView txtvTitle; private TextView txtvDuration; @@ -109,10 +106,9 @@ public class ItemFragment extends Fragment { private ImageView imgvCover; private ProgressBar progbarDownload; private ProgressBar progbarLoading; - private Button butAction1; - private Button butAction2; - private ImageButton butMore; - private PopupMenu popupMenu; + private IconButton butAction1; + private IconButton butAction2; + private Menu popupMenu; private Subscription subscription; @@ -125,7 +121,7 @@ public class ItemFragment extends Fragment { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); - setHasOptionsMenu(false); + setHasOptionsMenu(true); itemID = getArguments().getLong(ARG_FEEDITEM, -1); } @@ -134,15 +130,12 @@ public class ItemFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); - ((MainActivity) getActivity()).getSupportActionBar().setTitle(""); - Toolbar toolbar = ((MainActivity) getActivity()).getToolbar(); View layout = inflater.inflate(R.layout.feeditem_fragment, container, false); - header = inflater.inflate(R.layout.feeditem_fragment_header, toolbar, false); root = (ViewGroup) layout.findViewById(R.id.content_root); - txtvTitle = (TextView) header.findViewById(R.id.txtvTitle); - txtvDuration = (TextView) header.findViewById(R.id.txtvDuration); - txtvPublished = (TextView) header.findViewById(R.id.txtvPublished); + txtvTitle = (TextView) layout.findViewById(R.id.txtvTitle); + txtvDuration = (TextView) layout.findViewById(R.id.txtvDuration); + txtvPublished = (TextView) layout.findViewById(R.id.txtvPublished); if (Build.VERSION.SDK_INT >= 14) { // ellipsize is causing problems on old versions, see #448 txtvTitle.setEllipsize(TextUtils.TruncateAt.END); } @@ -172,81 +165,43 @@ public class ItemFragment extends Fragment { }); registerForContextMenu(webvDescription); - imgvCover = (ImageView) header.findViewById(R.id.imgvCover); - progbarDownload = (ProgressBar) header.findViewById(R.id.progbarDownload); + imgvCover = (ImageView) layout.findViewById(R.id.imgvCover); + progbarDownload = (ProgressBar) layout.findViewById(R.id.progbarDownload); progbarLoading = (ProgressBar) layout.findViewById(R.id.progbarLoading); - butAction1 = (Button) header.findViewById(R.id.butAction1); - butAction2 = (Button) header.findViewById(R.id.butAction2); - butMore = (ImageButton) header.findViewById(R.id.butMoreActions); - popupMenu = new PopupMenu(getActivity(), butMore); + butAction1 = (IconButton) layout.findViewById(R.id.butAction1); + butAction2 = (IconButton) layout.findViewById(R.id.butAction2); - butAction1.setOnClickListener(new View.OnClickListener() { - DefaultActionButtonCallback actionButtonCallback = new DefaultActionButtonCallback(getActivity()); - - @Override - - public void onClick(View v) { - if (item == null) { - return; - } - actionButtonCallback.onActionButtonPressed(item); - FeedMedia media = item.getMedia(); - if (media != null && media.isDownloaded()) { - // playback was started, dialog should close itself - ((MainActivity) getActivity()).dismissChildFragment(); - } - } - } - ); + butAction1.setOnClickListener(v -> { + if (item == null) { + return; + } + DefaultActionButtonCallback actionButtonCallback = new DefaultActionButtonCallback(getActivity()); + actionButtonCallback.onActionButtonPressed(item); + FeedMedia media = item.getMedia(); + if (media != null && media.isDownloaded()) { + // playback was started, dialog should close itself + ((MainActivity) getActivity()).dismissChildFragment(); + } + }); butAction2.setOnClickListener(v -> { - if (item == null) { - return; - } - - if (item.hasMedia()) { - FeedMedia media = item.getMedia(); - if (!media.isDownloaded()) { - DBTasks.playMedia(getActivity(), media, true, true, true); - ((MainActivity) getActivity()).dismissChildFragment(); - } else { - DBWriter.deleteFeedMediaOfItem(getActivity(), media.getId()); - } - } else if (item.getLink() != null) { - Uri uri = Uri.parse(item.getLink()); - getActivity().startActivity(new Intent(Intent.ACTION_VIEW, uri)); - } + if (item == null) { + return; } - ); - butMore.setOnClickListener(v -> { - if (item == null) { - return; - } - popupMenu.getMenu().clear(); - popupMenu.inflate(R.menu.feeditem_options); - if (item.hasMedia()) { - FeedItemMenuHandler.onPrepareMenu(getActivity(), popupMenuInterface, item, true, queue); + if (item.hasMedia()) { + FeedMedia media = item.getMedia(); + if (!media.isDownloaded()) { + DBTasks.playMedia(getActivity(), media, true, true, true); + ((MainActivity) getActivity()).dismissChildFragment(); } else { - // these are already available via button1 and button2 - FeedItemMenuHandler.onPrepareMenu(getActivity(), popupMenuInterface, item, true, queue, - R.id.mark_read_item, R.id.visit_website_item); + DBWriter.deleteFeedMediaOfItem(getActivity(), media.getId()); } - popupMenu.show(); + } else if (item.getLink() != null) { + Uri uri = Uri.parse(item.getLink()); + getActivity().startActivity(new Intent(Intent.ACTION_VIEW, uri)); } - ); - - popupMenu.setOnMenuItemClickListener(menuItem -> { - - try { - return FeedItemMenuHandler.onMenuItemClicked(getActivity(), menuItem.getItemId(), item); - } catch (DownloadRequestException e) { - e.printStackTrace(); - Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_LONG).show(); - return true; - } - } - ); + }); return layout; } @@ -254,8 +209,6 @@ public class ItemFragment extends Fragment { @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - Toolbar toolbar = ((MainActivity) getActivity()).getToolbar(); - toolbar.addView(header); load(); } @@ -279,7 +232,6 @@ public class ItemFragment extends Fragment { @Override public void onDestroyView() { super.onDestroyView(); - resetViewState(); if(subscription != null) { subscription.unsubscribe(); } @@ -289,15 +241,37 @@ public class ItemFragment extends Fragment { } } - private void resetViewState() { - Toolbar toolbar = ((MainActivity) getActivity()).getToolbar(); - toolbar.removeView(header); + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + if(item == null) { + return; + } + inflater.inflate(R.menu.feeditem_options, menu); + popupMenu = menu; + if (item.hasMedia()) { + FeedItemMenuHandler.onPrepareMenu(getActivity(), popupMenuInterface, item, true, queue); + } else { + // these are already available via button1 and button2 + FeedItemMenuHandler.onPrepareMenu(getActivity(), popupMenuInterface, item, true, queue, + R.id.mark_read_item, R.id.visit_website_item); + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem menuItem) { + try { + return FeedItemMenuHandler.onMenuItemClicked(getActivity(), menuItem.getItemId(), item); + } catch (DownloadRequestException e) { + e.printStackTrace(); + Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_LONG).show(); + return true; + } } private final FeedItemMenuHandler.MenuInterface popupMenuInterface = new FeedItemMenuHandler.MenuInterface() { @Override public void setItemVisibility(int id, boolean visible) { - MenuItem item = popupMenu.getMenu().findItem(id); + MenuItem item = popupMenu.findItem(id); if (item != null) { item.setVisible(visible); } @@ -319,7 +293,7 @@ public class ItemFragment extends Fragment { Log.d(TAG, "updateAppearance item is null"); return; } - + getActivity().supportInvalidateOptionsMenu(); txtvTitle.setText(item.getTitle()); if (item.getPubDate() != null) { @@ -347,54 +321,55 @@ public class ItemFragment extends Fragment { } FeedMedia media = item.getMedia(); + String butAction1Icon = null; + int butAction1Text = 0; + String butAction2Icon = null; + int butAction2Text = 0; if (media == null) { - TypedArray drawables = getActivity().obtainStyledAttributes(new int[]{R.attr.navigation_accept, - R.attr.location_web_site}); - if (!item.isPlayed()) { - butAction1.setCompoundDrawablesWithIntrinsicBounds(drawables.getDrawable(0), null, null, null); - butAction1.setText(getActivity().getString(R.string.mark_read_label)); - butAction1.setVisibility(View.VISIBLE); - } else { - butAction1.setVisibility(View.INVISIBLE); + butAction1Icon = "{fa-check 24sp}"; + butAction1Text = R.string.mark_read_label; } - if (item.getLink() != null) { - butAction2.setCompoundDrawablesWithIntrinsicBounds(drawables.getDrawable(1), null, null, null); - butAction2.setText(getActivity().getString(R.string.visit_website_label)); - } else { - butAction2.setEnabled(false); + butAction2Icon = "{ma-web 24sp}"; + butAction2Text = R.string.visit_website_label; } - - drawables.recycle(); - } else {if(media.getDuration() > 0) { + } else { + if(media.getDuration() > 0) { txtvDuration.setText(Converter.getDurationStringLong(media.getDuration())); } - boolean isDownloading = DownloadRequester.getInstance().isDownloadingFile(media); - TypedArray drawables = getActivity().obtainStyledAttributes(new int[]{R.attr.av_play, - R.attr.av_download, R.attr.action_stream, R.attr.content_discard, R.attr.navigation_cancel}); - if (!media.isDownloaded()) { - butAction2.setCompoundDrawablesWithIntrinsicBounds(drawables.getDrawable(2), null, null, null); - butAction2.setText(getActivity().getString(R.string.stream_label)); + butAction2Icon = "{md-settings-input-antenna 24sp}"; + butAction2Text = R.string.stream_label; } else { - butAction2.setCompoundDrawablesWithIntrinsicBounds(drawables.getDrawable(3), null, null, null); - butAction2.setText(getActivity().getString(R.string.remove_episode_lable)); + butAction2Icon = "{md-delete 24sp}"; + butAction2Text = R.string.remove_label; } - if (isDownloading) { - butAction1.setCompoundDrawablesWithIntrinsicBounds(drawables.getDrawable(4), null, null, null); - butAction1.setText(getActivity().getString(R.string.cancel_download_label)); + butAction1Icon = "{md-cancel 24sp}"; + butAction1Text = R.string.cancel_label; } else if (media.isDownloaded()) { - butAction1.setCompoundDrawablesWithIntrinsicBounds(drawables.getDrawable(0), null, null, null); - butAction1.setText(getActivity().getString(R.string.play_label)); + butAction1Icon = "{md-play-arrow 24sp}"; + butAction1Text = R.string.play_label; } else { - butAction1.setCompoundDrawablesWithIntrinsicBounds(drawables.getDrawable(1), null, null, null); - butAction1.setText(getActivity().getString(R.string.download_label)); + butAction1Icon = "{md-file-download 24sp}"; + butAction1Text = R.string.download_label; } - - drawables.recycle(); + } + if(butAction1Icon != null && butAction1Text != 0) { + butAction1.setText(butAction1Icon +"\u0020\u0020" + getActivity().getString(butAction1Text)); + Iconify.addIcons(butAction1); + butAction1.setVisibility(View.VISIBLE); + } else { + butAction1.setVisibility(View.INVISIBLE); + } + if(butAction2Icon != null && butAction2Text != 0) { + butAction2.setText(butAction2Icon +"\u0020\u0020" + getActivity().getString(butAction2Text)); + Iconify.addIcons(butAction2); + butAction2.setVisibility(View.VISIBLE); + } else { + butAction2.setVisibility(View.INVISIBLE); } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java index fbe2274a3..bc5024426 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java @@ -12,7 +12,6 @@ import android.os.Bundle; import android.support.v4.app.ListFragment; import android.support.v4.util.Pair; import android.support.v4.view.MenuItemCompat; -import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.SearchView; import android.util.Log; import android.view.ContextMenu; @@ -145,34 +144,26 @@ public class ItemlistFragment extends ListFragment { @Override public void onStart() { super.onStart(); - EventDistributor.getInstance().register(contentUpdate); - EventBus.getDefault().registerSticky(this); if (viewsCreated && itemsLoaded) { onFragmentLoaded(); } } - @Override - public void onStop() { - super.onStop(); - EventDistributor.getInstance().unregister(contentUpdate); - EventBus.getDefault().unregister(this); - if(subscription != null) { - subscription.unsubscribe(); - } - } - @Override public void onResume() { super.onResume(); - Log.d(TAG, "onResume()"); + EventDistributor.getInstance().register(contentUpdate); + EventBus.getDefault().registerSticky(this); + ((MainActivity)getActivity()).getSupportActionBar().setTitle(""); updateProgressBarVisibility(); loadItems(); } @Override - public void onDetach() { - super.onDetach(); + public void onPause() { + super.onPause(); + EventDistributor.getInstance().unregister(contentUpdate); + EventBus.getDefault().unregister(this); if(subscription != null) { subscription.unsubscribe(); } @@ -368,7 +359,6 @@ public class ItemlistFragment extends ListFragment { @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - ((ActionBarActivity) getActivity()).getSupportActionBar().setTitle(""); registerForContextMenu(getListView()); @@ -382,7 +372,9 @@ public class ItemlistFragment extends ListFragment { public void onListItemClick(ListView l, View v, int position, long id) { FeedItem selection = adapter.getItem(position - l.getHeaderViewsCount()); if (selection != null) { - ((MainActivity) getActivity()).loadChildFragment(ItemFragment.newInstance(selection.getId())); + MainActivity activity = (MainActivity) getActivity(); + activity.loadChildFragment(ItemFragment.newInstance(selection.getId())); + activity.getSupportActionBar().setTitle(feed.getTitle()); } } @@ -547,15 +539,12 @@ public class ItemlistFragment extends ListFragment { .dontAnimate() .into(imgvCover); - butShowInfo.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (viewsCreated && itemsLoaded) { - Intent startIntent = new Intent(getActivity(), FeedInfoActivity.class); - startIntent.putExtra(FeedInfoActivity.EXTRA_FEED_ID, - feed.getId()); - startActivity(startIntent); - } + butShowInfo.setOnClickListener(v -> { + if (viewsCreated && itemsLoaded) { + Intent startIntent = new Intent(getActivity(), FeedInfoActivity.class); + startIntent.putExtra(FeedInfoActivity.EXTRA_FEED_ID, + feed.getId()); + startActivity(startIntent); } }); } @@ -573,16 +562,13 @@ public class ItemlistFragment extends ListFragment { View header = inflater.inflate(R.layout.more_content_list_footer, lv, false); lv.addFooterView(header); listFooter = new MoreContentListFooterUtil(header); - listFooter.setClickListener(new MoreContentListFooterUtil.Listener() { - @Override - public void onClick() { - if (feed != null) { - try { - DBTasks.loadNextPageOfFeed(getActivity(), feed, false); - } catch (DownloadRequestException e) { - e.printStackTrace(); - DownloadRequestErrorDialogCreator.newRequestErrorDialog(getActivity(), e.getMessage()); - } + listFooter.setClickListener(() -> { + if (feed != null) { + try { + DBTasks.loadNextPageOfFeed(getActivity(), feed, false); + } catch (DownloadRequestException e) { + e.printStackTrace(); + DownloadRequestErrorDialogCreator.newRequestErrorDialog(getActivity(), e.getMessage()); } } }); @@ -629,7 +615,6 @@ public class ItemlistFragment extends ListFragment { if(subscription != null) { subscription.unsubscribe(); } - subscription = Observable.fromCallable(() -> loadData()) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java index 72704245f..e92df4885 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java @@ -2,21 +2,20 @@ package de.danoeh.antennapod.fragment; import android.content.Intent; import android.content.res.Resources; -import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v7.widget.SearchView; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.GridView; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.util.EntityUtils; +import com.squareup.okhttp.OkHttpClient; +import com.squareup.okhttp.Request; +import com.squareup.okhttp.Response; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -30,13 +29,23 @@ import java.util.List; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.OnlineFeedViewActivity; import de.danoeh.antennapod.adapter.itunes.ItunesAdapter; +import de.danoeh.antennapod.core.ClientConfig; import de.danoeh.antennapod.core.preferences.UserPreferences; +import de.danoeh.antennapod.core.service.download.AntennapodHttpClient; +import rx.Observable; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; import static de.danoeh.antennapod.adapter.itunes.ItunesAdapter.Podcast; //Searches iTunes store for given string and displays results in a list public class ItunesSearchFragment extends Fragment { - final String TAG = "ItunesSearchFragment"; + + private static final String TAG = "ItunesSearchFragment"; + + private static final String API_URL = "https://itunes.apple.com/search?media=podcast&term=%s"; + /** * Search input field */ @@ -52,6 +61,8 @@ public class ItunesSearchFragment extends Fragment { */ private List searchResults; + private Subscription subscription; + /** * Replace adapter data with provided search results from SearchTask. * @param result List of Podcast objects containing search results @@ -117,7 +128,7 @@ public class ItunesSearchFragment extends Fragment { //This prevents onQueryTextSubmit() from being called twice when keyboard is used //to submit the query. searchView.clearFocus(); - new SearchTask(s).execute(); + search(s); return false; } @@ -137,77 +148,59 @@ public class ItunesSearchFragment extends Fragment { return view; } - /** - * Search the iTunes store for podcasts using the given query - */ - class SearchTask extends AsyncTask { - /** - * Incomplete iTunes API search URL - */ - final String apiUrl = "https://itunes.apple.com/search?media=podcast&term=%s"; - - /** - * Search terms - */ - final String query; - - /** - * Search result - */ - final List taskData = new ArrayList<>(); - - /** - * Constructor - * - * @param query Search string - */ - public SearchTask(String query) { - String encodedQuery = null; - try { - encodedQuery = URLEncoder.encode(query, "UTF-8"); - } catch(UnsupportedEncodingException e) { - // this won't ever be thrown - } - if(encodedQuery != null) { - this.query = encodedQuery; - } else { - this.query = query; // failsafe - } + private void search(String query) { + if (subscription != null) { + subscription.unsubscribe(); } + subscription = rx.Observable.create((Observable.OnSubscribe>) subscriber -> { + String encodedQuery = null; + try { + encodedQuery = URLEncoder.encode(query, "UTF-8"); + } catch (UnsupportedEncodingException e) { + // this won't ever be thrown + } + if (encodedQuery == null) { + encodedQuery = query; // failsafe + } - //Get the podcast data - @Override - protected Void doInBackground(Void... params) { + //Spaces in the query need to be replaced with '+' character. + String formattedUrl = String.format(API_URL, query).replace(' ', '+'); - //Spaces in the query need to be replaced with '+' character. - String formattedUrl = String.format(apiUrl, query).replace(' ', '+'); + OkHttpClient client = AntennapodHttpClient.getHttpClient(); + Request.Builder httpReq = new Request.Builder() + .url(formattedUrl) + .header("User-Agent", ClientConfig.USER_AGENT); + List podcasts = new ArrayList<>(); + try { + Response response = client.newCall(httpReq.build()).execute(); - HttpClient client = new DefaultHttpClient(); - HttpGet get = new HttpGet(formattedUrl); + if(response.isSuccessful()) { + String resultString = response.body().string(); + JSONObject result = new JSONObject(resultString); + JSONArray j = result.getJSONArray("results"); - try { - HttpResponse response = client.execute(get); - String resultString = EntityUtils.toString(response.getEntity()); - JSONObject result = new JSONObject(resultString); - JSONArray j = result.getJSONArray("results"); - - for (int i = 0; i < j.length(); i++){ - JSONObject podcastJson = j.getJSONObject(i); - Podcast podcast = new Podcast(podcastJson); - taskData.add(podcast); - } - - } catch (IOException | JSONException e) { - e.printStackTrace(); - } - return null; - } - - //Save the data and update the list - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - updateData(taskData); - } + for (int i = 0; i < j.length(); i++) { + JSONObject podcastJson = j.getJSONObject(i); + Podcast podcast = new Podcast(podcastJson); + podcasts.add(podcast); + } + } + else { + subscriber.onError(new IOException("Unexpected error: " + response)); + } + } catch (IOException | JSONException e) { + Log.e(TAG, Log.getStackTraceString(e)); + } + subscriber.onNext(podcasts); + subscriber.onCompleted(); + }) + .subscribeOn(Schedulers.newThread()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(podcasts -> { + updateData(podcasts); + }, error -> { + Log.e(TAG, Log.getStackTraceString(error)); + }); } + } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java index 85586962f..64e3a7da7 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java @@ -1,6 +1,6 @@ package de.danoeh.antennapod.fragment; -import android.app.Activity; +import android.content.Context; import android.content.res.TypedArray; import android.os.Bundle; import android.support.v4.app.ListFragment; @@ -14,7 +14,6 @@ import android.view.View; import android.widget.ListView; import java.util.List; -import java.util.concurrent.atomic.AtomicReference; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; @@ -50,16 +49,13 @@ public class PlaybackHistoryFragment extends ListFragment { private boolean itemsLoaded = false; private boolean viewsCreated = false; - private AtomicReference activity = new AtomicReference(); - private List downloaderList; private Subscription subscription; @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - this.activity.set(activity); + public void onAttach(Context context) { + super.onAttach(context); if (viewsCreated && itemsLoaded) { onFragmentLoaded(); } @@ -123,7 +119,6 @@ public class PlaybackHistoryFragment extends ListFragment { if(subscription != null) { subscription.unsubscribe(); } - activity.set(null); } @Override @@ -138,7 +133,7 @@ public class PlaybackHistoryFragment extends ListFragment { DownloaderUpdate update = event.update; downloaderList = update.downloaders; if (adapter != null) { - adapter.notifyDataSetChanged(); + adapter.notifyDataSetChanged(); } } @@ -210,7 +205,8 @@ public class PlaybackHistoryFragment extends ListFragment { // played items shoudln't be transparent for this fragment since, *all* items // in this fragment will, by definition, be played. So it serves no purpose and can make // it harder to read. - adapter = new FeedItemlistAdapter(getActivity(), itemAccess, new DefaultActionButtonCallback(activity.get()), true, false); + adapter = new FeedItemlistAdapter(getActivity(), itemAccess, + new DefaultActionButtonCallback(getActivity()), true, false); setListAdapter(adapter); } setListShown(true); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java index 1271887b1..cc6b44f6a 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java @@ -10,6 +10,7 @@ import android.support.v4.view.MenuItemCompat; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.SearchView; +import android.support.v7.widget.SimpleItemAnimator; import android.support.v7.widget.helper.ItemTouchHelper; import android.util.Log; import android.view.LayoutInflater; @@ -365,7 +366,10 @@ public class QueueFragment extends Fragment { View root = inflater.inflate(R.layout.queue_fragment, container, false); infoBar = (TextView) root.findViewById(R.id.info_bar); recyclerView = (RecyclerView) root.findViewById(R.id.recyclerView); - recyclerView.getItemAnimator().setSupportsChangeAnimations(false); + RecyclerView.ItemAnimator animator = recyclerView.getItemAnimator(); + if (animator instanceof SimpleItemAnimator) { + ((SimpleItemAnimator) animator).setSupportsChangeAnimations(false); + } layoutManager = new LinearLayoutManager(getActivity()); recyclerView.setLayoutManager(layoutManager); recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity()).build()); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagFragment.java index e2450f03d..d39829260 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagFragment.java @@ -45,7 +45,7 @@ public class TagFragment extends PodcastListFragment { @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - ((MainActivity) getActivity()).getMainActivtyActionBar().setTitle(tag.getTitle()); + ((MainActivity) getActivity()).getSupportActionBar().setTitle(tag.getTitle()); } @Override diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java index 5bd567a2f..338f02e61 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java @@ -80,7 +80,7 @@ public class TagListFragment extends ListFragment { @Override public void onResume() { super.onResume(); - ((MainActivity) getActivity()).getMainActivtyActionBar().setTitle(R.string.add_feed_label); + ((MainActivity) getActivity()).getSupportActionBar().setTitle(R.string.add_feed_label); } @Override diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/SwitchCompatPreference.java b/app/src/main/java/de/danoeh/antennapod/preferences/SwitchCompatPreference.java new file mode 100644 index 000000000..10c11b88e --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/preferences/SwitchCompatPreference.java @@ -0,0 +1,37 @@ +package de.danoeh.antennapod.preferences; + +import android.annotation.TargetApi; +import android.content.Context; +import android.os.Build; +import android.preference.CheckBoxPreference; +import android.util.AttributeSet; + +import de.danoeh.antennapod.R; + +public class SwitchCompatPreference extends CheckBoxPreference { + + public SwitchCompatPreference(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(); + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public SwitchCompatPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(); + } + + public SwitchCompatPreference(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public SwitchCompatPreference(Context context) { + super(context); + init(); + } + + private void init() { + setWidgetLayoutResource(R.layout.preference_switch_layout); + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/shadow.xml b/app/src/main/res/drawable/shadow.xml new file mode 100644 index 000000000..fc5110e0b --- /dev/null +++ b/app/src/main/res/drawable/shadow.xml @@ -0,0 +1,7 @@ + + + diff --git a/app/src/main/res/layout/feeditem_fragment.xml b/app/src/main/res/layout/feeditem_fragment.xml index 5e1b580d2..3dd4e134d 100644 --- a/app/src/main/res/layout/feeditem_fragment.xml +++ b/app/src/main/res/layout/feeditem_fragment.xml @@ -1,13 +1,141 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -22,4 +150,4 @@ android:layout_gravity="center" android:indeterminate="true" /> - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/feeditem_fragment_header.xml b/app/src/main/res/layout/feeditem_fragment_header.xml deleted file mode 100644 index 2534dddbe..000000000 --- a/app/src/main/res/layout/feeditem_fragment_header.xml +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - -