Correction of nasty requestFeature bug! No more transactions, simply an inflater add view.

No longer necessary classes removed.
Simplification of DynamicDialogFragment
Add task button now correctly shows on SDK 19
This commit is contained in:
bg45
2017-04-05 12:46:06 -04:00
parent 4db0bfcf8c
commit 6f1926c9b1
13 changed files with 55 additions and 115 deletions

View File

@@ -8,8 +8,8 @@ android {
applicationId "com.wismna.geoffroy.donext" applicationId "com.wismna.geoffroy.donext"
minSdkVersion 19 minSdkVersion 19
targetSdkVersion 25 targetSdkVersion 25
versionCode 19 versionCode 20
versionName "1.4.4" versionName "1.4.5"
} }
buildTypes { buildTypes {
release { release {

View File

@@ -185,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 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) if (mIsLargeLayout)
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,7 +1,6 @@
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;
@@ -75,7 +74,7 @@ public class TodayActivity extends AppCompatActivity
String title = getString(R.string.action_today_select); String title = getString(R.string.action_today_select);
FragmentManager fragmentManager = getSupportFragmentManager(); FragmentManager fragmentManager = getSupportFragmentManager();
if (isLargeLayout && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) if (isLargeLayout)
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,13 +5,10 @@ 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;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
@@ -22,6 +19,7 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.FrameLayout;
import com.wismna.geoffroy.donext.R; import com.wismna.geoffroy.donext.R;
@@ -32,9 +30,8 @@ import com.wismna.geoffroy.donext.R;
*/ */
public abstract class DynamicDialogFragment extends DialogFragment { public abstract class DynamicDialogFragment extends DialogFragment {
private View mDialogView = null;
boolean mHasNeutralButton = false; boolean mHasNeutralButton = false;
Fragment mContentFragment = new Fragment(); int mContentLayoutId = 0;
@Nullable @Nullable
@Override @Override
@@ -52,30 +49,12 @@ 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);
insertContentView(view, inflater);
return view; return view;
} }
// TODO: find a way to correct this // This basically returns null
// 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); return super.onCreateView(inflater, container, savedInstanceState);
} }
else {
// Returns the saved view from Dialog Builder on large screens
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
@@ -86,7 +65,7 @@ public abstract class DynamicDialogFragment extends DialogFragment {
@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);
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 // Set the dialog buttons
builder.setView(view) builder.setView(view)
// Add action buttons // Add action buttons
.setPositiveButton(args.getString("button_positive"), new DialogInterface.OnClickListener() { .setPositiveButton(args.getString("button_positive"), new DialogInterface.OnClickListener() {
@@ -111,9 +90,7 @@ public abstract class DynamicDialogFragment extends DialogFragment {
}); });
} }
setToolbarTitle(view); setToolbarTitle(view);
// Save the View so that it can returned by onCreateView insertContentView(view, inflater);
// (otherwise it is null and it poses problems when committing child fragment transactions)
mDialogView = view;
return builder.create(); return builder.create();
} }
@@ -179,6 +156,12 @@ public abstract class DynamicDialogFragment extends DialogFragment {
super.onDestroyView(); super.onDestroyView();
} }
/** Helper function to get a View, without having to worry about the fact that is a Dialog or not*/
protected View findViewById(int id) {
if (getShowsDialog()) return getDialog().findViewById(id);
return getView().findViewById(id);
}
/** 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);
@@ -186,6 +169,15 @@ public abstract class DynamicDialogFragment extends DialogFragment {
return toolbar; return toolbar;
} }
/** Inserts the actual contents in the content Frame Layout */
private void insertContentView(View view, LayoutInflater inflater) {
// Ensure that the content view is set
if (mContentLayoutId == 0) return;
// Insert the content view
FrameLayout content = (FrameLayout) view.findViewById(R.id.dynamic_fragment_content);
content.addView(inflater.inflate(mContentLayoutId, (ViewGroup) view.getParent()));
}
protected abstract void onPositiveButtonClick(View view); protected abstract void onPositiveButtonClick(View view);
protected abstract void onNeutralButtonClick(View view); protected abstract void onNeutralButtonClick(View view);

View File

@@ -1,24 +0,0 @@
package com.wismna.geoffroy.donext.fragments;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.wismna.geoffroy.donext.R;
/**
* Created by bg45 on 2017-03-21.
* Content fragment for the Task Form Dialog fragment.
*/
public class TaskFormContentFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.content_task_form, container, false);
}
}

View File

@@ -55,7 +55,7 @@ public class TaskFormDialogFragment extends DynamicDialogFragment {
@Override @Override
public void onCreate(@Nullable Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mContentFragment = new TaskFormContentFragment(); mContentLayoutId = R.layout.content_task_form;
Bundle args = getArguments(); Bundle args = getArguments();
if (args != null) { if (args != null) {
mHasNeutralButton = args.getBoolean("neutral"); mHasNeutralButton = args.getBoolean("neutral");
@@ -67,7 +67,7 @@ public class TaskFormDialogFragment extends DynamicDialogFragment {
super.onStart(); super.onStart();
// Set Task Form specific information at that point because we are sure that the view is // Set Task Form specific information at that point because we are sure that the view is
// entirely inflated (with the content fragment) // entirely inflated (with the content fragment)
setTaskValues(getView()); setTaskValues();
} }
@Override @Override
@@ -94,10 +94,9 @@ public class TaskFormDialogFragment extends DynamicDialogFragment {
dismiss(); dismiss();
} }
private void setTaskValues(View view) { private void setTaskValues() {
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) 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
ArrayAdapter<TaskList> adapter = new ArrayAdapter<>( ArrayAdapter<TaskList> adapter = new ArrayAdapter<>(
getActivity(), android.R.layout.simple_spinner_item, taskLists); getActivity(), android.R.layout.simple_spinner_item, taskLists);
@@ -110,16 +109,16 @@ public class TaskFormDialogFragment extends DynamicDialogFragment {
int id = args.getInt("list"); int id = args.getInt("list");
spinner.setSelection(id); spinner.setSelection(id);
CheckBox checkBox = (CheckBox) view.findViewById(R.id.new_task_today); CheckBox checkBox = (CheckBox) findViewById(R.id.new_task_today);
TextView todayLabel = (TextView) view.findViewById(R.id.new_task_today_label); TextView todayLabel = (TextView) findViewById(R.id.new_task_today_label);
boolean isTodayActive = args.getBoolean("today"); boolean isTodayActive = args.getBoolean("today");
checkBox.setVisibility(isTodayActive ? View.VISIBLE : View.GONE); checkBox.setVisibility(isTodayActive ? View.VISIBLE : View.GONE);
todayLabel.setVisibility(isTodayActive ? View.VISIBLE : View.GONE); todayLabel.setVisibility(isTodayActive ? View.VISIBLE : View.GONE);
// Get date picker // Get date picker
final DatePicker dueDatePicker = (DatePicker) view.findViewById(R.id.new_task_due_date); final DatePicker dueDatePicker = (DatePicker) findViewById(R.id.new_task_due_date);
// Handle due date spinner depending on check box // Handle due date spinner depending on check box
CheckBox setDueDate = (CheckBox) view.findViewById(R.id.new_task_due_date_set); CheckBox setDueDate = (CheckBox) findViewById(R.id.new_task_due_date_set);
setDueDate.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { setDueDate.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
@@ -130,11 +129,11 @@ public class TaskFormDialogFragment extends DynamicDialogFragment {
// Set other properties if they exist // Set other properties if they exist
if (task != null) { if (task != null) {
EditText titleText = (EditText) view.findViewById(R.id.new_task_name); EditText titleText = (EditText) findViewById(R.id.new_task_name);
titleText.setText(task.getName()); titleText.setText(task.getName());
EditText descText = (EditText) view.findViewById(R.id.new_task_description); EditText descText = (EditText) findViewById(R.id.new_task_description);
descText.setText(task.getDescription()); descText.setText(task.getDescription());
SeekBar seekBar = (SeekBar) view.findViewById(R.id.new_task_priority); SeekBar seekBar = (SeekBar) findViewById(R.id.new_task_priority);
seekBar.setProgress(task.getPriority()); seekBar.setProgress(task.getPriority());
// Set Due Date // Set Due Date

View File

@@ -3,7 +3,6 @@ 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;
@@ -158,7 +157,7 @@ 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 (isLargeLayout && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (isLargeLayout) {
taskDialogFragment.show(manager, title); taskDialogFragment.show(manager, title);
} }
else { else {

View File

@@ -1,23 +0,0 @@
package com.wismna.geoffroy.donext.fragments;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.wismna.geoffroy.donext.R;
/**
* Created by bg45 on 2017-03-21.
* Contains the Today Form contents.
*/
public class TodayFormContentFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.content_today_form, container, false);
}
}

View File

@@ -48,15 +48,14 @@ public class TodayFormDialogFragment extends DynamicDialogFragment {
@Override @Override
public void onCreate(@Nullable Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mContentFragment = new TodayFormContentFragment(); mContentLayoutId = R.layout.content_today_form;
// Load the tasks asynchronously // Load the tasks asynchronously
new LoadTasks().execute(getActivity()); new LoadTasks().execute(getActivity());
} }
private void setLayoutValues(View view, List<Task> tasks) { private void setLayoutValues(List<Task> tasks) {
if (view == null) return; EditText editText = (EditText) findViewById(R.id.today_search);
EditText editText = (EditText) view.findViewById(R.id.today_search); final ListView listView = (ListView) 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);
listView.setAdapter(adapter); listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@@ -120,7 +119,7 @@ public class TodayFormDialogFragment extends DynamicDialogFragment {
@Override @Override
protected void onPostExecute(List<Task> tasks) { protected void onPostExecute(List<Task> tasks) {
super.onPostExecute(tasks); super.onPostExecute(tasks);
setLayoutValues(getView(), tasks); setLayoutValues(tasks);
} }
} }

View File

@@ -16,15 +16,6 @@
<include layout="@layout/toolbar" android:id="@+id/toolbar" /> <include layout="@layout/toolbar" android:id="@+id/toolbar" />
</android.support.design.widget.AppBarLayout> </android.support.design.widget.AppBarLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="@dimen/fab_margin"
android:onClick="onNewTaskClick"
android:src="@drawable/ic_add" />
<android.support.percent.PercentRelativeLayout <android.support.percent.PercentRelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@@ -43,4 +34,14 @@
android:background="@android:color/background_light" android:background="@android:color/background_light"
app:layout_behavior="@string/appbar_scrolling_view_behavior" /> app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.percent.PercentRelativeLayout> </android.support.percent.PercentRelativeLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="@dimen/fab_margin"
android:onClick="onNewTaskClick"
android:src="@drawable/ic_add" />
</android.support.design.widget.CoordinatorLayout> </android.support.design.widget.CoordinatorLayout>

View File

@@ -4,7 +4,6 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:background="@android:color/background_light"> android:background="@android:color/background_light">
<RelativeLayout <RelativeLayout
android:id="@+id/new_task_layout" android:id="@+id/new_task_layout"

View File

@@ -3,7 +3,6 @@
android:orientation="vertical" android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:focusable="true" android:focusable="true"
android:focusableInTouchMode="true" android:focusableInTouchMode="true"
android:background="@android:color/background_light" > android:background="@android:color/background_light" >

View File

@@ -14,11 +14,11 @@
<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"
android:layout_marginTop="?attr/actionBarSize" >
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize"
android:text="@string/incompatible_sdk_version"/> android:text="@string/incompatible_sdk_version"/>
</FrameLayout> </FrameLayout>