Change message body font size with slider, using new setTextZoom() WebView API, from 40% to 250%

This commit is contained in:
Sergii Pylypenko 2014-01-31 23:09:25 +02:00
parent abb3318846
commit 67abde055a
7 changed files with 281 additions and 2 deletions

View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2012 Jay Weisskopf
Licensed under the MIT License (see LICENSE.txt)
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/slider_preference_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dip"
android:paddingLeft="16dip"
android:paddingRight="16dip"
android:paddingTop="8dip" >
<TextView
android:id="@+android:id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<SeekBar
android:id="@+id/slider_preference_seekbar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="12dip"
android:paddingTop="12dip" />
</LinearLayout>

View file

@ -55,4 +55,8 @@
<attr name="contactPictureFallbackDefaultBackgroundColor" format="reference|color"/>
</declare-styleable>
<declare-styleable name="SliderPreference">
<attr name="android:summary" />
</declare-styleable>
</resources>

View file

@ -153,6 +153,12 @@
android:entryValues="@array/font_values_webview"
android:dialogTitle="@string/font_size_message_view_content" />
<com.fsck.k9.activity.setup.SliderPreference
android:persistent="false"
android:key="message_view_content_font_slider"
android:title="@string/font_size_message_view_content"
android:dialogTitle="@string/font_size_message_view_content" />
</PreferenceScreen>
<PreferenceScreen

View file

@ -28,6 +28,7 @@ public class FontSizes {
private static final String MESSAGE_VIEW_SUBJECT = "fontSizeMessageViewSubject";
private static final String MESSAGE_VIEW_DATE = "fontSizeMessageViewDate";
private static final String MESSAGE_VIEW_CONTENT = "fontSizeMessageViewContent";
private static final String MESSAGE_VIEW_CONTENT_PERCENT = "fontSizeMessageViewContentPercent";
private static final String MESSAGE_COMPOSE_INPUT = "fontSizeMessageComposeInput";
/*
@ -116,10 +117,18 @@ public class FontSizes {
/**
* Font size of the message content in the message view activity.
*
* Note: The unit is WebSettings.TextSize
* Note: The unit is WebSettings.TextSize, this option is used only on Android 3.2 (API level 13) and below.
*/
private TextSize messageViewContent = TextSize.NORMAL;
/**
* Font size of the message content in the message view activity, as percent from default size.
*
* Note: This option is used only on Android 4.0 (API level 14) and above.
*/
private int messageViewContentPercent;
/**
* Font size for the input fields in the message compose activity.
*/
@ -147,6 +156,7 @@ public class FontSizes {
messageViewAdditionalHeaders = FONT_DEFAULT;
messageViewSubject = FONT_DEFAULT;
messageViewDate = FONT_DEFAULT;
messageViewContentPercent = 100;
messageComposeInput = MEDIUM;
}
@ -175,6 +185,7 @@ public class FontSizes {
editor.putInt(MESSAGE_VIEW_SUBJECT, messageViewSubject);
editor.putInt(MESSAGE_VIEW_DATE, messageViewDate);
editor.putInt(MESSAGE_VIEW_CONTENT, getMessageViewContentAsInt());
editor.putInt(MESSAGE_VIEW_CONTENT_PERCENT, getMessageViewContentAsPercent());
editor.putInt(MESSAGE_COMPOSE_INPUT, messageComposeInput);
}
@ -203,6 +214,7 @@ public class FontSizes {
messageViewSubject = prefs.getInt(MESSAGE_VIEW_SUBJECT, messageViewSubject);
messageViewDate = prefs.getInt(MESSAGE_VIEW_DATE, messageViewDate);
setMessageViewContent(prefs.getInt(MESSAGE_VIEW_CONTENT, 3));
setMessageViewContentAsPercent(prefs.getInt(MESSAGE_VIEW_CONTENT_PERCENT, 100));
messageComposeInput = prefs.getInt(MESSAGE_COMPOSE_INPUT, messageComposeInput);
}
@ -359,6 +371,14 @@ public class FontSizes {
}
}
public int getMessageViewContentAsPercent() {
return messageViewContentPercent;
}
public void setMessageViewContentAsPercent(int size) {
messageViewContentPercent = size;
}
public int getMessageComposeInput() {
return messageComposeInput;
}

View file

@ -19,6 +19,7 @@ public class FontSizeSettings extends K9PreferenceActivity {
/*
* Keys of the preferences defined in res/xml/font_preferences.xml
*/
private static final String PREFERENCE_SCREEN_MESSAGE_VIEW_FONTS = "message_view_fonts";
private static final String PREFERENCE_ACCOUNT_NAME_FONT = "account_name_font";
private static final String PREFERENCE_ACCOUNT_DESCRIPTION_FONT = "account_description_font";
private static final String PREFERENCE_FOLDER_NAME_FONT = "folder_name_font";
@ -34,6 +35,7 @@ public class FontSizeSettings extends K9PreferenceActivity {
private static final String PREFERENCE_MESSAGE_VIEW_SUBJECT_FONT = "message_view_subject_font";
private static final String PREFERENCE_MESSAGE_VIEW_DATE_FONT = "message_view_date_font";
private static final String PREFERENCE_MESSAGE_VIEW_CONTENT_FONT = "message_view_content_font";
private static final String PREFERENCE_MESSAGE_VIEW_CONTENT_FONT_SLIDER = "message_view_content_font_slider";
private static final String PREFERENCE_MESSAGE_COMPOSE_INPUT_FONT = "message_compose_input_font";
private ListPreference mAccountName;
@ -51,8 +53,11 @@ public class FontSizeSettings extends K9PreferenceActivity {
private ListPreference mMessageViewSubject;
private ListPreference mMessageViewDate;
private ListPreference mMessageViewContent;
private SliderPreference mMessageViewContentSlider;
private ListPreference mMessageComposeInput;
private static final int FONT_PERCENT_MIN = 40;
private static final int FONT_PERCENT_MAX = 250;
/**
* Start the FontSizeSettings activity.
@ -120,6 +125,41 @@ public class FontSizeSettings extends K9PreferenceActivity {
PREFERENCE_MESSAGE_VIEW_CONTENT_FONT,
Integer.toString(fontSizes.getMessageViewContentAsInt()));
mMessageViewContentSlider = (SliderPreference) findPreference(
PREFERENCE_MESSAGE_VIEW_CONTENT_FONT_SLIDER);
// Scale to [0, 1]
mMessageViewContentSlider.setValue((float)
(fontSizes.getMessageViewContentAsPercent() - FONT_PERCENT_MIN) /
(FONT_PERCENT_MAX - FONT_PERCENT_MIN));
mMessageViewContentSlider.setOnPreferenceChangeListener(
new Preference.OnPreferenceChangeListener() {
// Show the preference value in the preference summary field.
@Override
public boolean onPreferenceChange(final Preference preference, final Object newValue) {
final SliderPreference slider = (SliderPreference) preference;
final Float value = (Float) newValue;
// Scale from [0, 1]
slider.setSummary(String.valueOf((int)(FONT_PERCENT_MIN +
value * (FONT_PERCENT_MAX - FONT_PERCENT_MIN))) + "%");
slider.setDialogTitle(slider.getTitle() + " " + slider.getSummary());
if (slider.getDialog() != null) {
slider.getDialog().setTitle(slider.getDialogTitle());
}
return true;
}
}
);
mMessageViewContentSlider.getOnPreferenceChangeListener().onPreferenceChange(
mMessageViewContentSlider, new Float(mMessageViewContentSlider.getValue()));
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
((PreferenceGroup) findPreference(PREFERENCE_SCREEN_MESSAGE_VIEW_FONTS)).
removePreference(mMessageViewContent);
} else {
((PreferenceGroup) findPreference(PREFERENCE_SCREEN_MESSAGE_VIEW_FONTS)).
removePreference(mMessageViewContentSlider);
}
mMessageComposeInput = setupListPreference(
PREFERENCE_MESSAGE_COMPOSE_INPUT_FONT,
Integer.toString(fontSizes.getMessageComposeInput()));
@ -150,6 +190,10 @@ public class FontSizeSettings extends K9PreferenceActivity {
fontSizes.setMessageViewSubject(Integer.parseInt(mMessageViewSubject.getValue()));
fontSizes.setMessageViewDate(Integer.parseInt(mMessageViewDate.getValue()));
fontSizes.setMessageViewContent(Integer.parseInt(mMessageViewContent.getValue()));
// Scale from [0, 1]
fontSizes.setMessageViewContentAsPercent((int)(FONT_PERCENT_MIN +
mMessageViewContentSlider.getValue() *
(FONT_PERCENT_MAX - FONT_PERCENT_MIN)));
fontSizes.setMessageComposeInput(Integer.parseInt(mMessageComposeInput.getValue()));

View file

@ -0,0 +1,172 @@
/*
* Copyright 2012 Jay Weisskopf
*
* Licensed under the MIT License (see LICENSE.txt)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies
* or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Source: https://github.com/jayschwa/AndroidSliderPreference
*/
package com.fsck.k9.activity.setup;
import android.content.Context;
import android.content.res.TypedArray;
import android.preference.DialogPreference;
import android.util.AttributeSet;
import android.view.View;
import android.widget.SeekBar;
import com.fsck.k9.*;
/**
* @author Jay Weisskopf
*/
public class SliderPreference extends DialogPreference {
protected final static int SEEKBAR_RESOLUTION = 10000;
protected float mValue;
protected int mSeekBarValue;
protected CharSequence[] mSummaries;
/**
* @param context
* @param attrs
*/
public SliderPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setup(context, attrs);
}
/**
* @param context
* @param attrs
* @param defStyle
*/
public SliderPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setup(context, attrs);
}
private void setup(Context context, AttributeSet attrs) {
setDialogLayoutResource(R.layout.slider_preference_dialog);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SliderPreference);
try {
setSummary(a.getTextArray(R.styleable.SliderPreference_android_summary));
} catch (Exception e) {
// Do nothing
}
a.recycle();
}
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getFloat(index, 0);
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
setValue(restoreValue ? getPersistedFloat(mValue) : (Float) defaultValue);
}
@Override
public CharSequence getSummary() {
if (mSummaries != null && mSummaries.length > 0) {
int index = (int) (mValue * mSummaries.length);
index = Math.min(index, mSummaries.length - 1);
return mSummaries[index];
} else {
return super.getSummary();
}
}
public void setSummary(CharSequence[] summaries) {
mSummaries = summaries;
}
@Override
public void setSummary(CharSequence summary) {
super.setSummary(summary);
mSummaries = null;
}
@Override
public void setSummary(int summaryResId) {
try {
setSummary(getContext().getResources().getStringArray(summaryResId));
} catch (Exception e) {
super.setSummary(summaryResId);
}
}
public float getValue() {
return mValue;
}
public void setValue(float value) {
value = Math.max(0, Math.min(value, 1)); // clamp to [0, 1]
if (shouldPersist()) {
persistFloat(value);
}
if (value != mValue) {
mValue = value;
notifyChanged();
}
}
@Override
protected View onCreateDialogView() {
mSeekBarValue = (int) (mValue * SEEKBAR_RESOLUTION);
View view = super.onCreateDialogView();
SeekBar seekbar = (SeekBar) view.findViewById(R.id.slider_preference_seekbar);
seekbar.setMax(SEEKBAR_RESOLUTION);
seekbar.setProgress(mSeekBarValue);
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
SliderPreference.this.mSeekBarValue = progress;
callChangeListener((float) SliderPreference.this.mSeekBarValue / SEEKBAR_RESOLUTION);
}
}
});
return view;
}
@Override
protected void onDialogClosed(boolean positiveResult) {
final float newValue = (float) mSeekBarValue / SEEKBAR_RESOLUTION;
if (positiveResult && callChangeListener(newValue)) {
setValue(newValue);
} else {
callChangeListener(mValue);
}
super.onDialogClosed(positiveResult);
}
// TODO: Save and restore preference state.
}

View file

@ -109,7 +109,11 @@ public class MessageWebView extends RigidWebView {
disableOverscrolling();
webSettings.setTextSize(K9.getFontSizes().getMessageViewContent());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
webSettings.setTextZoom(K9.getFontSizes().getMessageViewContentAsPercent());
} else {
webSettings.setTextSize(K9.getFontSizes().getMessageViewContent());
}
// Disable network images by default. This is overridden by preferences.
blockNetworkData(true);