Search code examples
javaandroidandroid-preferences

Android preferences how to make an info preference


In my android app I have settings activity, which uses preferences.

There are many preferences such as ListPreference, SwitchPreference, etc., but there aren't one kind of preference that I need.

In this preference I want to:
1. display a title that is constant and will never change (such as other preferences)
2. display text, that will be changed by the app, but NOT by the user.

Most similar preference to this is EditTextPreference, but it's not OK for me, because I don't want user to change displayed text, instead my app will change it. So my preference could be called TextViewPreference.

Good example of what I want is inside the 'Settings' android app, inside the 'device information' category.

Edit: Code that I would like to use to change summary won't be placed in activity code, and I don't use PreferenceActivity.
In fact, only time when I have to change the summary is when the SettingsActivity is NOT on main thread.


Solution

  • The code below is a complete example of what you are trying to achieve, it shows an example of how to create an info preference that is directly updated based on other preferences (addition of x_pref and y_pref and displaying result in result_pref below) or is updated based on something passed from another activity.

    1) DemoActivity----------

    public class DemoActivity extends AppCompatActivity{
    
    
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.demo_activity);
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.demo_preferences, menu);
        return super.onCreateOptionsMenu(menu);
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    
        switch(item.getItemId()) {
            case R.id.menu_settings:
                Intent i = new Intent(DemoActivity.this , PrefDemoActivity.class);
                i.putExtra("Passed", "Test--##%%&&");
                startActivity(i);
                break;
            default:
                throw new RuntimeException("unknown menu selection");
        }
    
        return true;
    }
    }
    

    2) demo_activity.xml----------

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="Empty"
        android:gravity="center"
        android:background="@android:color/holo_blue_light"/>
    
    </android.support.constraint.ConstraintLayout>
    

    3) PrefDemoActivity----------

    public class PrefDemoActivity extends AppCompatActivity {
    
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        FragmentManager mFragmentManager = getFragmentManager();
        FragmentTransaction mFragmentTransaction = mFragmentManager
                .beginTransaction();
        DemoEditPreferences mDemoPrefsFragment = new DemoEditPreferences();
        mFragmentTransaction.replace(android.R.id.content, mDemoPrefsFragment);
        mFragmentTransaction.commit();
    
    }
    }
    

    4) DemEditPreferences----------

    public class DemoEditPreferences extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener{
    
    private SharedPreferences demo_preferences;
    private int preferencesToEdit;
    
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        demo_preferences = getActivity().getSharedPreferences("demo_preference",
                0);
    
        preferencesToEdit = R.xml.demo_preferences;
        String preferenceName = getResources().getString(R.string.pref_sensor_key);
    
        PreferenceManager preferenceManager = getPreferenceManager();
        preferenceManager.setSharedPreferencesName(preferenceName);
        preferenceManager.setSharedPreferencesMode(0);
    
        getActivity().setTitle("Demo Preferences");
    
        addPreferencesFromResource(preferencesToEdit);
    
        Preference from_another_activity_p = (Preference) findPreference("passed_from_another_activity_key");
    
        if(getActivity().getIntent() != null) {
    
            from_another_activity_p.setSummary(getActivity().getIntent().getStringExtra("Passed"));
        }
    
        updateResult();
    
        for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) {
            initSummary(getPreferenceScreen().getPreference(i));
        }
    
    }
    
    
    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    
        if(findPreference(key) != null) {
    
            if(findPreference(key).getKey().equals("x_key")) {
    
                updateResult();
    
            }else if(findPreference(key).getKey().equals("y_key")) {
    
    
                updateResult();
    
            }
    
            checkPrefValueValidity(findPreference(key));
            updatePrefSummary(findPreference(key));
        }
    
    }
    
    private void updateResult(){
    
        EditTextPreference x_p = (EditTextPreference) findPreference("x_key");
        EditTextPreference y_p = (EditTextPreference) findPreference("y_key");
        Preference result_p = (Preference) findPreference("result_key");
        result_p.setSummary("( X + Y ) = " + (Float.valueOf(x_p.getText()) + Float.valueOf(y_p.getText())));
    
    }
    
    private void initSummary(Preference p) {
        if (p instanceof PreferenceCategory) {
            PreferenceCategory pCategory = (PreferenceCategory) p;
            for (int i = 0; i < pCategory.getPreferenceCount(); i++) {
                initSummary(pCategory.getPreference(i));
            }
        } else {
            updatePrefSummary(p);
        }
    }
    
    private void updatePrefSummary(Preference p) {
        if (p instanceof ListPreference) {
            ListPreference listPref = (ListPreference) p;
            p.setSummary(listPref.getEntry());
        }
        if (p instanceof EditTextPreference) {
            EditTextPreference editTextPref = (EditTextPreference) p;
            p.setSummary(editTextPref.getText());
        }
    }
    
    private void checkPrefValueValidity(Preference p) {
        if (p instanceof EditTextPreference) {
            EditTextPreference editTextPref = (EditTextPreference) p;
            if (editTextPref.getText().equals("")) {
                // what do you want to do if the value entered is empty
            } else {
                // maybe only certain values are allowed
            }
        }
    }
    
    
    @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;
    }
    
    @Override
    public void onResume() {
        super.onResume();
        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
    }
    
    @Override
    public void onPause() {
        super.onPause();
        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
    }
    
    }
    

    5) demo_menu----------

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
    
    <item android:id="@+id/menu_settings"
        android:title="Settings"
        android:titleCondensed="Settings"
        android:orderInCategory="1">
    </item>
    
    </menu>
    

    7) demo_preferences----------

    <?xml version="1.0" encoding="utf-8"?>
    <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    
    <PreferenceCategory
        android:title="Demo">
    
        <EditTextPreference
            android:key="x_key"
            android:title="X"
            android:defaultValue="0"
            android:summary="0"
            android:inputType="numberDecimal|numberSigned"
            android:selectAllOnFocus="true"
            android:singleLine="true">
        </EditTextPreference>
    
        <EditTextPreference
            android:key="y_key"
            android:title="Y"
            android:defaultValue="0"
            android:summary="0"
            android:inputType="numberDecimal|numberSigned"
            android:selectAllOnFocus="true"
            android:singleLine="true">
        </EditTextPreference>
    
        <Preference
            android:key="result_key"
            android:title="Result"
            android:summary="0"> // default summary value if any
        </Preference>
    
        <Preference
            android:key="passed_from_another_activity_key"
            android:title="From another Activity"
            android:summary="null"> // default summary value if any
        </Preference>
    
    </PreferenceCategory>
    
    </PreferenceScreen>
    

    8) Don't forget to add both activities to the manifest.