Daydream's setting page is crashing on load - android

I am making a Plain Text Daydream on android and cannot open the settings screen. The rest of the daydream runs fine, but the settings don't. This is the settings xml:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<EditTextPreference
android:key="pref_text"
android:title="Text on daydream"
android:dialogTitle="Text on daydream:"
android:defaultValue="Hello world!" />
</PreferenceScreen>
I'm using PreferenceFragments too. I assume it's the XML, but just in case here are the fragment and activity too:
public class SettingsFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.settings);
}
}
and
public class SettingsActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Display the fragment as the main content.
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new SettingsFragment())
.commit();
}
}
How do I fix it?

All I had to do was set the settings activity as the default. Then it's fixed!

Related

How can I create a Setting activity

I created a Setting activity in my app, but it didn't work.
This is my SettingFragment class:
public class SettingFragment extends PreferenceFragmentCompat
{
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey)
{
setPreferencesFromResource(R.xml.pref, rootKey);
}
}
This is my SettingActivity:
public class SettingActivity extends AppCompatActivity
{
#Override
protected void onCreate(#Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content, new SettingFragment())
.commit();
}
}
This is MainActivity. Clicking the button will open SettingActivity.
btn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
Intent intent = new Intent(MainActivity.this, SettingActivity.class);
startActivity(intent);
}
});
And this is Preference.xml:
<PreferenceScreen
xmlns:app="http://schemas.android.com/apk/res-auto">
<Preference
app:key="feedback"
app:title="Send feedback"
app:summary="Report technical issues or suggest new features"/>
</PreferenceScreen>
What is the R.id.content? It was used in the developer.android site example.
What is the problem? How can I solve this?
What is the R.id.content?
Lets assume that this is the SettingActivity layout file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SettingsActivity">
<LinearLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp" >
</LinearLayout>
</LinearLayout>
The call to replace will swap your fragment with R.id.content. You can also call replace with android.R.id.content, read more here.
You need to use android.R.id.content. This will replace the root content with the Fragment's content. you can find more information about android.R.id.content from this
// Display the fragment as the main content.
getSupportFragmentManager()
.beginTransaction()
.replace(android.R.id.content, new SettingFragment())
.commit();

Display preference fragments in a full view

I am using a preference fragment and replacing the fragment in the id of the root layout of the main xml file. So my problem is that the preferences are displaying alongside with the main activity xml elements.
I have seen in Android apps that the preferences open up separately I am not sure whether they do open up separately or just occupying the entire screen. For opening the preference fragment I am doing a normal fragment transaction(Note: I am not using the support library not sure if this has something to do with my problem but still mentioning it).
Here is what the problem is,
And so here is my code
sampleprefs.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:defaultValue="false"
android:title="Check box preference"
android:key="check_box_preference_1" />
<EditTextPreference
android:defaultValue="Default value"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="Edit text preference"
android:key="edit_text_preference_1" />
</PreferenceScreen>
Here is the main layout,
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.random.preferenceexample.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:id="#+id/textView" />
<Button
android:text="Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/button" />
</LinearLayout>
This is my Main Activity code where the fragment displays on the click of a button,
public class MainActivity extends Activity implements View.OnClickListener {
boolean result;
Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button)findViewById(R.id.button);
button.setOnClickListener(this);
}
#Override
public void onClick(View v) {
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
SettingsFragment sf = new SettingsFragment();
ft.add(R.id.activity_main,sf);
ft.commit();
}
This is the fragment class
public class SettingsFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.sampleprefs);
}
}
It looks the problem seems to be with the background transparency of Fragment. Fragments are transparent backgrounded by default because they can be used to paint only a small portion of the screen but if you want your Fragment to cover fullscreen then just add some background to it, it will work.
Moreover, it's good practice to use a root layout which supports views to be placed one above the other(for ex. FrameLayout) for FragmentTransactions.
Add these in your Fragment :
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
view.setBackgroundColor(getResources().getColor(android.R.color.white));
return view;
}
Here is the working example

Android testing preferences fragment by Expresso

I have got a problem with testing my code by Expresso. I wrote this code:
public class SettingsActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new SettingsFragment())
.commit();
}
public class SettingsFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/preferences_xml">
<PreferenceCategory
android:title="#string/application_settings"
android:id="#+id/application_settings_preferences">
<CheckBoxPreference
android:key="#string/key_processing_private_data_preference"
android:title="#string/title_processing_private_data_preference"
android:summary="#string/summary_processing_private_data_preference"
android:defaultValue="true"
android:dependency="#string/key_recording_audio_preference"
android:id="#+id/private_data_check_box_preference"/>
</PreferenceCategory>
<PreferenceCategory
android:title="#string/device_settings"
android:id="#+id/device_settings_preferences">
<CheckBoxPreference
android:key="#string/key_recording_audio_preference"
android:title="#string/title_recording_audio_preference"
android:summary="#string/summary_recording_audio_preference"
android:defaultValue="true"
android:id="#+id/recording_audio_check_box_preference"/>
</PreferenceCategory>
</PreferenceScreen>
My test rule:
#Rule
public ActivityTestRule<SettingsActivity> mActivityRule = new ActivityTestRule<>(
SettingsActivity.class);
I try test first checkbox:
onData(anything())
.inAdapterView(allOf(
isDescendantOfA(withId(R.id.preferences_xml)),
withId(R.id.application_settings_preferences)))
.atPosition(1)
.check(matches(isDisplayed()));
Test always fail with NoMatchingViewException: No views in hierarchy found matching:
http://prntscr.com/bv8xlb
And also I try:
String workingInBackgroundSummary = mActivityRule.getActivity().getBaseContext().getString(R.string.summary_working_in_background_preference);
onData(withSummaryText(workingInBackgroundSummary)).check(matches(isDisplayed()));
Test always fail with NullPointerException:
http://prntscr.com/bv8w04.
onView(withId(R.id.working_in_background_check_box_preference)).check(matches(isDisplayed()));
Also fail with NoMatchingViewException.
Would someone show an example with correct test case?
(Posted on behalf of the OP).
Solved:
onData(allOf(
is(instanceOf(Preference.class)),
withKey(key),
withSummary(R.string.summary_working_in_background_preference),
withTitle(R.string.title_working_in_background_preference)))
.onChildView(withText(title))
.check(matches(isCompletelyDisplayed()));

How to have ActionBar in PreferenceActivity?

I have an android app with a UserSettingsActivity derived from PreferenceActivity. When I open this activity, no menu bar is shown.
In order to have the 'bar' or 'action bar' on top of the settings screen, I searched for it in google on found this link and this link. Because the first answer seems outdated, I tried the suggestion in the second link which does not work. Therefore I am posting this question again.. Here are the pieces of code I am using:
preferences.xml ( I added just the android.support.v7.widget.Toolbar part):
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
app:navigationContentDescription="#string/abc_action_bar_up_description"
android:background="?attr/colorPrimary"
app:navigationIcon="?attr/homeAsUpIndicator"
app:title="#string/action_settings"
/>
<ListPreference
android:title="#string/UpdateInterval"
android:summary="#string/UpdateIntervalText"
android:key="updateInterval"
android:defaultValue="24"
android:entries="#array/listArray"
android:entryValues="#array/listValues" />
<ListPreference
android:title="#string/LimitSetting"
android:summary="#string/LimitSettingText"
android:key="limitSetting"
android:entries="#array/limitArray"
android:entryValues="#array/limitValues" />
<Preference
android:key="reset"
android:title="Reset database"
android:summary="This will remove every entry in the database"
/>
</PreferenceScreen>
and UserSettingsActivity.java (I added the onPostCreate part):
public class UserSettingActivity extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content, new MyPreferenceFragment()).commit();
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent();
Toolbar bar = (Toolbar) LayoutInflater.from(this).inflate(R.xml.preferences, root, false);
root.addView(bar, 0); // insert at top
bar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
public class MyPreferenceFragment extends PreferenceFragment {
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences); // <<-- ERROR HERE
// doing something here
}
}
}
However, I get the following error:
Caused by: java.lang.ClassCastException: android.support.v7.widget.Toolbar cannot be cast to android.preference.Preference
on the marked line. Without the added pieces in those two files the app did work, without the (action)-bar, however...
What seems to be the problem here?
Try this.
Extend your activity with AppCompatActivity
Then add toolbar. Refer here: -http://coderzpassion.com/android-working-with-material-design/
PreferenceActivity is now deprecated. Use PreferenceFragment inside any other activity, which can be extended from any parent activity other than PreferenceActivity

PreferenceActivity: set icon in action bar

I use a PreferenceActivity with encapsulated preference screens.
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:key="prefs" >
<PreferenceScreen android:title="#string/pref_user_1" >
some text preference
</PreferenceScreen>
<PreferenceScreen android:title="#string/pref_user_2" >
some prefs
<PreferenceScreen android:title="#string/pref_user_2_1" >
some prefs
</PreferenceScreen>
</PreferenceScreen>
</PreferenceScreen>
my inherited preferenceActivity class has the folowing onCreate method
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Display the fragment as the main content.
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new PrefsFragment()).commit();
}
and has an inner class
public static class PrefsFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener {
public PrefsFragment() {
super();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.myprefs);
...
}
in the first screen I get the correct icon in the action bar (I call it Action Bar even if I haven't the <) but I would like to change the icon in the following screen.
I have tried getActivity().getActionBar().setIcon(R.drawable.ic_act); in the inner class and also in the preferenceActivity, but it doesn't change anything.
Does someone know how to do it, if possible?

Categories

Resources