Workaround for nasty requestFeature bug in Android versions < 23: dialogs will open fullscreen in this case

Layout size is recalculated after rotation
Some code cleanup
This commit is contained in:
bg45
2017-04-04 16:51:07 -04:00
parent 954055cbe9
commit 4db0bfcf8c
10 changed files with 45 additions and 39 deletions

View File

@@ -176,7 +176,6 @@ public class MainActivity extends AppCompatActivity implements TasksFragment.Tas
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putInt("list", currentTabPosition); args.putInt("list", currentTabPosition);
args.putBoolean("layout", mIsLargeLayout);
args.putBoolean("today", sharedPref.getBoolean("pref_conf_today_enable", false)); args.putBoolean("today", sharedPref.getBoolean("pref_conf_today_enable", false));
args.putBoolean("neutral", false); args.putBoolean("neutral", false);
args.putString("button_positive", getString(R.string.new_task_save)); args.putString("button_positive", getString(R.string.new_task_save));
@@ -186,7 +185,7 @@ public class MainActivity extends AppCompatActivity implements TasksFragment.Tas
String title = getString(R.string.action_new_task); String title = getString(R.string.action_new_task);
FragmentManager fragmentManager = getSupportFragmentManager(); FragmentManager fragmentManager = getSupportFragmentManager();
if (mIsLargeLayout) if (mIsLargeLayout && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
taskDialogFragment.show(fragmentManager, title); taskDialogFragment.show(fragmentManager, title);
else { else {
// The device is smaller, so show the fragment fullscreen // The device is smaller, so show the fragment fullscreen

View File

@@ -1,6 +1,7 @@
package com.wismna.geoffroy.donext.activities; package com.wismna.geoffroy.donext.activities;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.design.widget.FloatingActionButton; import android.support.design.widget.FloatingActionButton;
@@ -22,8 +23,6 @@ import com.wismna.geoffroy.donext.fragments.TodayFormDialogFragment;
public class TodayActivity extends AppCompatActivity public class TodayActivity extends AppCompatActivity
implements TodayFormDialogFragment.TodayTaskListener { implements TodayFormDialogFragment.TodayTaskListener {
private boolean mIsLargeLayout;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@@ -39,8 +38,6 @@ public class TodayActivity extends AppCompatActivity
ab.setDisplayHomeAsUpEnabled(true); ab.setDisplayHomeAsUpEnabled(true);
ab.setHomeButtonEnabled(true); ab.setHomeButtonEnabled(true);
} }
mIsLargeLayout = getResources().getBoolean(R.bool.large_layout);
} }
@Override @Override
@@ -68,16 +65,17 @@ public class TodayActivity extends AppCompatActivity
TodayFormDialogFragment taskDialogFragment = TodayFormDialogFragment taskDialogFragment =
TodayFormDialogFragment.newInstance(TodayActivity.this); TodayFormDialogFragment.newInstance(TodayActivity.this);
boolean isLargeLayout = getResources().getBoolean(R.bool.large_layout);
// Set some configuration values for the dialog // Set some configuration values for the dialog
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putBoolean("layout", mIsLargeLayout); args.putBoolean("layout", isLargeLayout);
args.putString("button_positive", getString(R.string.new_task_save)); args.putString("button_positive", getString(R.string.new_task_save));
args.putString("button_negative", getString(R.string.new_task_cancel)); args.putString("button_negative", getString(R.string.new_task_cancel));
taskDialogFragment.setArguments(args); taskDialogFragment.setArguments(args);
String title = getString(R.string.action_today_select); String title = getString(R.string.action_today_select);
FragmentManager fragmentManager = getSupportFragmentManager(); FragmentManager fragmentManager = getSupportFragmentManager();
if (mIsLargeLayout) if (isLargeLayout && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
taskDialogFragment.show(fragmentManager, title); taskDialogFragment.show(fragmentManager, title);
else { else {
// The device is smaller, so show the fragment fullscreen // The device is smaller, so show the fragment fullscreen

View File

@@ -5,6 +5,7 @@ import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
@@ -33,14 +34,13 @@ import com.wismna.geoffroy.donext.R;
public abstract class DynamicDialogFragment extends DialogFragment { public abstract class DynamicDialogFragment extends DialogFragment {
private View mDialogView = null; private View mDialogView = null;
boolean mHasNeutralButton = false; boolean mHasNeutralButton = false;
boolean mIsLargeLayout = false;
Fragment mContentFragment = new Fragment(); Fragment mContentFragment = new Fragment();
@Nullable @Nullable
@Override @Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// This part is only needed on small layouts (large layouts use onCreateDialog) // This part is only needed on small layouts (large layouts use onCreateDialog)
if (!mIsLargeLayout) { if (!getShowsDialog()) {
View view = inflater.inflate(R.layout.fragment_dynamic_dialog, container, false); View view = inflater.inflate(R.layout.fragment_dynamic_dialog, container, false);
AppCompatActivity activity = (AppCompatActivity) getActivity(); AppCompatActivity activity = (AppCompatActivity) getActivity();
activity.setSupportActionBar(setToolbarTitle(view)); activity.setSupportActionBar(setToolbarTitle(view));
@@ -52,13 +52,30 @@ public abstract class DynamicDialogFragment extends DialogFragment {
actionBar.setHomeAsUpIndicator(android.R.drawable.ic_menu_close_clear_cancel); actionBar.setHomeAsUpIndicator(android.R.drawable.ic_menu_close_clear_cancel);
} }
setHasOptionsMenu(true); setHasOptionsMenu(true);
setContentFragment();
return view; return view;
} }
//return super.onCreateView(inflater, container, savedInstanceState); // TODO: find a way to correct this
// Handle nasty bug: requestFeature() must be called before adding content
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// This returns null. No content will be loaded in dialog mode, but no errors either.
return super.onCreateView(inflater, container, savedInstanceState);
}
else {
// Returns the saved view from Dialog Builder on large screens // Returns the saved view from Dialog Builder on large screens
return mDialogView; return mDialogView;
} }
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Get the child fragment manager (and not the "main" one)
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
// Set the actual content of the fragment
transaction.replace(R.id.dynamic_fragment_content, mContentFragment);
// Commit the transaction instantly
transaction.commitNow();
}
@Override @Override
@NonNull @NonNull
@@ -67,7 +84,6 @@ public abstract class DynamicDialogFragment extends DialogFragment {
LayoutInflater inflater = getActivity().getLayoutInflater(); LayoutInflater inflater = getActivity().getLayoutInflater();
// As it is a Dialog, the root ViewGroup can be null without issues // As it is a Dialog, the root ViewGroup can be null without issues
@SuppressLint("InflateParams") final View view = inflater.inflate(R.layout.fragment_dynamic_dialog, null); @SuppressLint("InflateParams") final View view = inflater.inflate(R.layout.fragment_dynamic_dialog, null);
setToolbarTitle(view);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
Bundle args = getArguments(); Bundle args = getArguments();
// Pass null as the parent view because its going in the dialog layout // Pass null as the parent view because its going in the dialog layout
@@ -94,7 +110,7 @@ public abstract class DynamicDialogFragment extends DialogFragment {
} }
}); });
} }
setContentFragment(); setToolbarTitle(view);
// Save the View so that it can returned by onCreateView // Save the View so that it can returned by onCreateView
// (otherwise it is null and it poses problems when committing child fragment transactions) // (otherwise it is null and it poses problems when committing child fragment transactions)
mDialogView = view; mDialogView = view;
@@ -163,17 +179,6 @@ public abstract class DynamicDialogFragment extends DialogFragment {
super.onDestroyView(); super.onDestroyView();
} }
private void setContentFragment() {
// Get the child fragment manager (and not the "normal" one)
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
// Set the actual content of the fragment
transaction.replace(R.id.dynamic_fragment_content, mContentFragment);
// Commit the transaction instantly
transaction.commitNow();
}
/** Sets the title of the Fragment from the Tag */ /** Sets the title of the Fragment from the Tag */
private Toolbar setToolbarTitle(View view) { private Toolbar setToolbarTitle(View view) {
Toolbar toolbar = (Toolbar) view.findViewById(R.id.dialog_toolbar); Toolbar toolbar = (Toolbar) view.findViewById(R.id.dialog_toolbar);

View File

@@ -15,6 +15,7 @@ import com.wismna.geoffroy.donext.R;
*/ */
public class TaskFormContentFragment extends Fragment { public class TaskFormContentFragment extends Fragment {
@Nullable @Nullable
@Override @Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {

View File

@@ -58,7 +58,6 @@ public class TaskFormDialogFragment extends DynamicDialogFragment {
mContentFragment = new TaskFormContentFragment(); mContentFragment = new TaskFormContentFragment();
Bundle args = getArguments(); Bundle args = getArguments();
if (args != null) { if (args != null) {
mIsLargeLayout = args.getBoolean("layout");
mHasNeutralButton = args.getBoolean("neutral"); mHasNeutralButton = args.getBoolean("neutral");
} }
} }
@@ -96,7 +95,7 @@ public class TaskFormDialogFragment extends DynamicDialogFragment {
} }
private void setTaskValues(View view) { private void setTaskValues(View view) {
if (view == null) return;
// Populate spinner with task lists // Populate spinner with task lists
Spinner spinner = (Spinner) view.findViewById(R.id.new_task_list); Spinner spinner = (Spinner) view.findViewById(R.id.new_task_list);
// Create an ArrayAdapter using the string array and a default spinner layout // Create an ArrayAdapter using the string array and a default spinner layout

View File

@@ -3,6 +3,7 @@ package com.wismna.geoffroy.donext.fragments;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
@@ -54,7 +55,6 @@ public class TasksFragment extends Fragment implements
private static final String TASK_LIST_ID = "task_list_id"; private static final String TASK_LIST_ID = "task_list_id";
private long taskListId = -1; private long taskListId = -1;
private boolean mIsLargeLayout;
private boolean isTodayView = true; private boolean isTodayView = true;
private TaskRecyclerViewAdapter taskRecyclerViewAdapter; private TaskRecyclerViewAdapter taskRecyclerViewAdapter;
private View view; private View view;
@@ -84,7 +84,6 @@ public class TasksFragment extends Fragment implements
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mIsLargeLayout = getResources().getBoolean(R.bool.large_layout);
if (getArguments() != null) { if (getArguments() != null) {
taskListId = getArguments().getLong(TASK_LIST_ID); taskListId = getArguments().getLong(TASK_LIST_ID);
} }
@@ -121,10 +120,10 @@ public class TasksFragment extends Fragment implements
new RecyclerItemClickListener(context, new RecyclerItemClickListener.OnItemClickListener() { new RecyclerItemClickListener(context, new RecyclerItemClickListener.OnItemClickListener() {
@Override @Override
public void onItemClick(View view, int position) { public void onItemClick(View view, int position) {
boolean isLargeLayout = getResources().getBoolean(R.bool.large_layout);
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext()); SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext());
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putInt("position", position); args.putInt("position", position);
args.putBoolean("layout", mIsLargeLayout);
args.putBoolean("today", sharedPref.getBoolean("pref_conf_today_enable", false)); args.putBoolean("today", sharedPref.getBoolean("pref_conf_today_enable", false));
args.putBoolean("neutral", true); args.putBoolean("neutral", true);
args.putString("button_positive", getString(R.string.new_task_save)); args.putString("button_positive", getString(R.string.new_task_save));
@@ -159,8 +158,9 @@ public class TasksFragment extends Fragment implements
// Open the fragment as a dialog or as full-screen depending on screen size // Open the fragment as a dialog or as full-screen depending on screen size
String title = getString(R.string.action_edit_task); String title = getString(R.string.action_edit_task);
if (mIsLargeLayout) if (isLargeLayout && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
taskDialogFragment.show(manager, title); taskDialogFragment.show(manager, title);
}
else { else {
// The device is smaller, so show the fragment fullscreen // The device is smaller, so show the fragment fullscreen
FragmentTransaction transaction = manager.beginTransaction(); FragmentTransaction transaction = manager.beginTransaction();

View File

@@ -45,20 +45,16 @@ public class TodayFormDialogFragment extends DynamicDialogFragment {
return fragment; return fragment;
} }
@Override @Override
public void onCreate(@Nullable Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mContentFragment = new TodayFormContentFragment(); mContentFragment = new TodayFormContentFragment();
// Load the tasks asynchronously // Load the tasks asynchronously
new LoadTasks().execute(getActivity()); new LoadTasks().execute(getActivity());
Bundle args = getArguments();
if (args != null) {
mIsLargeLayout = args.getBoolean("layout");
}
} }
private void setLayoutValues(View view, List<Task> tasks) { private void setLayoutValues(View view, List<Task> tasks) {
if (view == null) return;
EditText editText = (EditText) view.findViewById(R.id.today_search); EditText editText = (EditText) view.findViewById(R.id.today_search);
final ListView listView = (ListView) view.findViewById(R.id.today_tasks); final ListView listView = (ListView) view.findViewById(R.id.today_tasks);
final TodayArrayAdapter adapter = new TodayArrayAdapter(getActivity(), tasks); final TodayArrayAdapter adapter = new TodayArrayAdapter(getActivity(), tasks);

View File

@@ -14,6 +14,12 @@
<FrameLayout <FrameLayout
android:id="@+id/dynamic_fragment_content" android:id="@+id/dynamic_fragment_content"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize"
android:text="@string/incompatible_sdk_version"/>
</FrameLayout>
</android.support.design.widget.CoordinatorLayout> </android.support.design.widget.CoordinatorLayout>

View File

@@ -57,4 +57,5 @@
<string name="today_search_hint">Rechercher…</string> <string name="today_search_hint">Rechercher…</string>
<string name="action_today_select">Choisissez des tâches</string> <string name="action_today_select">Choisissez des tâches</string>
<string name="task_list_edit_list_hint">Nom de la liste</string> <string name="task_list_edit_list_hint">Nom de la liste</string>
<string name="incompatible_sdk_version">Sorry, your Android version is not supported.</string>
</resources> </resources>

View File

@@ -76,4 +76,5 @@
<string name="today_search_hint">Search…</string> <string name="today_search_hint">Search…</string>
<string name="action_today_select">Select tasks</string> <string name="action_today_select">Select tasks</string>
<string name="task_list_edit_list_hint">List name</string> <string name="task_list_edit_list_hint">List name</string>
<string name="incompatible_sdk_version">Sorry, your Android version is not supported.</string>
</resources> </resources>