diff --git a/app/src/main/java/org/fdroid/fdroid/views/main/MainViewController.java b/app/src/main/java/org/fdroid/fdroid/views/main/MainViewController.java
index 234a6ebe4..d67ca6f2b 100644
--- a/app/src/main/java/org/fdroid/fdroid/views/main/MainViewController.java
+++ b/app/src/main/java/org/fdroid/fdroid/views/main/MainViewController.java
@@ -1,6 +1,7 @@
package org.fdroid.fdroid.views.main;
import android.content.Intent;
+import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.view.View;
@@ -8,6 +9,7 @@ import android.widget.Button;
import android.widget.FrameLayout;
import org.fdroid.fdroid.R;
+import org.fdroid.fdroid.views.fragments.PreferencesFragment;
import org.fdroid.fdroid.views.myapps.MyAppsViewBinder;
import org.fdroid.fdroid.views.swap.SwapWorkflowActivity;
@@ -72,6 +74,20 @@ class MainViewController extends RecyclerView.ViewHolder {
});
}
+ /**
+ * Attaches a {@link PreferencesFragment} to the view. Everything else is managed by the
+ * fragment itself, so no further work needs to be done by this view binder.
+ *
+ * Note: It is tricky to attach a {@link Fragment} to a view from this view holder. This is due
+ * to the way in which the {@link RecyclerView} will reuse existing views and ask us to
+ * put a settings fragment in there at arbitrary times. Usually it wont be the same view we
+ * attached the fragment to last time, which causes weirdness. The solution is to use code from
+ * the com.lsjwzh.widget.recyclerviewpager.FragmentStatePagerAdapter which manages this.
+ * The code has been ported to {@link SettingsView}.
+ *
+ * @see SettingsView
+ */
public void bindSettingsView() {
+ activity.getLayoutInflater().inflate(R.layout.main_tab_settings, frame, true);
}
}
diff --git a/app/src/main/java/org/fdroid/fdroid/views/main/SettingsView.java b/app/src/main/java/org/fdroid/fdroid/views/main/SettingsView.java
new file mode 100644
index 000000000..afd8f2121
--- /dev/null
+++ b/app/src/main/java/org/fdroid/fdroid/views/main/SettingsView.java
@@ -0,0 +1,89 @@
+package org.fdroid.fdroid.views.main;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v7.app.AppCompatActivity;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+
+import org.fdroid.fdroid.R;
+import org.fdroid.fdroid.views.fragments.PreferencesFragment;
+
+/**
+ * When attached to the window, the {@link PreferencesFragment} will be added. When detached from
+ * the window, the fragment will be removed.
+ *
+ * Based on code from https://github.com/lsjwzh/RecyclerViewPager/blob/master/lib/src/main/java/com/lsjwzh/widget/recyclerviewpager/FragmentStatePagerAdapter.java
+ * licensed under the Apache 2.0 license (https://github.com/lsjwzh/RecyclerViewPager/blob/master/LICENSE).
+ * @see android.support.v4.app.FragmentStatePagerAdapter Much of the code here was ported from this class.
+ */
+public class SettingsView extends FrameLayout {
+
+ private FragmentTransaction currentTransaction;
+
+ public SettingsView(Context context) {
+ super(context);
+ setId(R.id.preference_fragment_parent);
+ }
+
+ public SettingsView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setId(R.id.preference_fragment_parent);
+ }
+
+ public SettingsView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ setId(R.id.preference_fragment_parent);
+ }
+
+ @TargetApi(21)
+ public SettingsView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ setId(R.id.preference_fragment_parent);
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ AppCompatActivity activity = (AppCompatActivity) getContext();
+ if (activity == null) {
+ throw new IllegalArgumentException("Cannot add a SettingsView to activities which are not an AppCompatActivity");
+ }
+
+ if (currentTransaction == null) {
+ currentTransaction = activity.getSupportFragmentManager().beginTransaction();
+ }
+
+ currentTransaction.replace(getId(), new PreferencesFragment(), "preferences-fragment");
+ currentTransaction.commitAllowingStateLoss();
+ currentTransaction = null;
+ activity.getSupportFragmentManager().executePendingTransactions();
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+
+ AppCompatActivity activity = (AppCompatActivity) getContext();
+ if (activity == null) {
+ throw new IllegalArgumentException("Cannot add a SettingsView to activities which are not an AppCompatActivity");
+ }
+
+ Fragment existingFragment = activity.getSupportFragmentManager().findFragmentByTag("preferences-fragment");
+ if (existingFragment == null) {
+ return;
+ }
+
+ if (currentTransaction == null) {
+ currentTransaction = activity.getSupportFragmentManager().beginTransaction();
+ }
+ currentTransaction.remove(existingFragment);
+ currentTransaction.commitAllowingStateLoss();
+ currentTransaction = null;
+ activity.getSupportFragmentManager().executePendingTransactions();
+ }
+
+}
diff --git a/app/src/main/res/layout/main_tab_settings.xml b/app/src/main/res/layout/main_tab_settings.xml
new file mode 100644
index 000000000..97d338420
--- /dev/null
+++ b/app/src/main/res/layout/main_tab_settings.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml
index c2fc8ac10..46c7bf804 100644
--- a/app/src/main/res/values/ids.xml
+++ b/app/src/main/res/values/ids.xml
@@ -2,6 +2,7 @@
+