9

ProgressDialog我可以知道是否可以在 内更改消息显示的字体DialogFragment

public class LoadFromCloudTaskFragment extends DialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        this.progressDialog = new ProgressDialog(this.getActivity());
        this.progressDialog.setMessage(progressMessage);
        this.progressDialog.setCanceledOnTouchOutside(false);

        return progressDialog;
    }

通过继承创建自定义类ProgressDialog可能是其中一种方式。但是,我想知道有没有更好的选择?可悲的是,我们没有ProgressDialog.Builder.

我尝试过的一种选择是

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    this.progressDialog = new ProgressDialog(this.getActivity());
    this.progressDialog.setMessage(progressMessage);
    this.progressDialog.setCanceledOnTouchOutside(false);

    Utils.setCustomFont(this.progressDialog.findViewById(android.R.id.message), Utils.ROBOTO_LIGHT_FONT);

    return progressDialog;
}

但这会给我错误

android.util.AndroidRuntimeException: requestFeature() 必须在添加内容之前调用

4

4 回答 4

4
Typeface font = Typeface.createFromAsset(getContext().getAssets(), "fonts/Roboto-Regular.ttf");
SpannableStringBuilder spannableSB = new SpannableStringBuilder(getString(R.string.text_please_wait));
spannableSB.setSpan (new CustomTypefaceSpan("fonts/Roboto-Regular.ttf", font), 0, spannableSB.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
loadDialog = ProgressDialog.show(this, null, spannableSB, true, false);

public class CustomTypefaceSpan extends TypefaceSpan {

    private final Typeface newType;

    public CustomTypefaceSpan(String family, Typeface type) {
       super(getContext(),family);
       newType = type;
    }

    @Override
    public void updateDrawState(TextPaint ds) {
         applyCustomTypeFace(ds, newType);
    }

    @Override
    public void updateMeasureState(TextPaint paint) {
        applyCustomTypeFace(paint, newType);
    }

    private static void applyCustomTypeFace(Paint paint, Typeface tf) {
        int oldStyle;
        Typeface old = paint.getTypeface();
        if (old == null) {
            oldStyle = 0;
        } else {
            oldStyle = old.getStyle();
        }

        int fake = oldStyle & ~tf.getStyle();
        if ((fake & Typeface.BOLD) != 0) {
            paint.setFakeBoldText(true);
        }

        if ((fake & Typeface.ITALIC) != 0) {
            paint.setTextSkewX(-0.25f);
        }

        paint.setTypeface(tf);
    }
}
于 2014-08-05T15:22:27.503 回答
3

从文档中可以看出:http: //developer.android.com/reference/android/app/DialogFragment.html

public static class MyDialogFragment extends DialogFragment {
    static MyDialogFragment newInstance() {
        return new MyDialogFragment();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.hello_world, container, false);
        View tv = v.findViewById(R.id.text);
        ((TextView)tv).setText("This is an instance of MyDialogFragment");
        return v;
    }
}

我怀疑您可以为 DialogFragment 提供自定义布局 XML。

在我继续使用此实用程序类设置字体之后:

import java.util.Hashtable;
import java.util.Map;

import android.content.Context;
import android.graphics.Typeface;
import android.widget.TextView;

/**
 * Taken from bug on b.android.com
 * https://code.google.com/p/android/issues/detail?id=9904
 * <p>
 * Optimizes way to work with typefaces and avoids context related memory leak
 * */
public class Typefaces {

    private static final Map<String, Typeface> cache = new Hashtable<String, Typeface>();

    public static Typeface get(Context c, String name) {
        synchronized (cache) {
            if (!cache.containsKey(name)) {
                Typeface t = Typeface.createFromAsset(c.getAssets(),
                        String.format("fonts/%s.ttf", name));
                cache.put(name, t);
            }
            return cache.get(name);
        }
    }

    public static Typeface _default(Context c) {
        return get(c, "verdana");
    }

    public static void setFonts(Context c, TextView... tvs) {
        for (TextView t : tvs) {
            if (t != null)
                t.setTypeface(_default(c));
        }
    }

}

假设您放置了自定义字体assets/fonts/verdana.ttf(如果使用_default()方法)

于 2013-03-01T18:30:00.487 回答
3

建议的解决方案之一如下。但我认为这不是一个好方法。非常欢迎任何进一步的建议。

public class ProgressDialogEx extends ProgressDialog {
    public ProgressDialogEx(Context context) {
        super(context);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        View view = this.findViewById(android.R.id.message);
        if (view != null) {
            // Shouldn't be null. Just to be paranoid enough.
            Utils.setCustomTypeface(view, Utils.ROBOTO_LIGHT_FONT);
        }
    }
}

public class LoadFromCloudTaskFragment extends DialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        this.progressDialog = new ProgressDialogEx(this.getActivity());
        this.progressDialog.setMessage(progressMessage);
        this.progressDialog.setCanceledOnTouchOutside(false);

        return progressDialog;
    }

Utils.setCustomTypeface

public static final Typeface ROBOTO_LIGHT_TYPE_FACE = Typeface.createFromAsset(MyApplication.instance().getAssets(), "fonts/Roboto-Light.ttf");

public static void setCustomTypeface(View view, Typeface typeFace) {
    if (view instanceof TextView) {
        ((TextView)view).setTypeface(typeFace);
    } else if (view instanceof EditText) {
        ((EditText)view).setTypeface(typeFace);
    } else if (view instanceof ViewGroup) {
        ViewGroup viewGroup = (ViewGroup)view;
        int count = viewGroup.getChildCount();
        for (int i = 0; i < count; i++) {
            setCustomTypeface(viewGroup.getChildAt(i), typeFace);
        }
    }
}
于 2013-03-01T18:41:48.850 回答
2

虽然这是一个老问题,但我整理了一些可能对未来访客有所帮助的信息。

在我开始之前,这不是即时设置。它只能在 ProgressDialog 初始化时完成,并且只适用于内置字体。既然都说了,那我们就开始吧!首先,我们需要在您的文件中使用 的父级创建一个样式android:Theme.Holo.Dialog,如下所示。styles.xml

<style name="CustomFontDialog" parent="android:Theme.Holo.Dialog">
    <item name="android:typeface">monospace</item>
</style>

然后在你的初始化中添加一点:

ProgressDialog prog = new ProgressDialog(new ContextThemeWrapper(context, R.style.CustomFontDialog)));

不过,为了使这个答案尽可能接近这个问题的答案,我正在研究一个名为Calligraphy的库,通过对问题的响应,开发人员计划将功能添加到对话框中。书法最终可能是您想要使用的,但现在您必须对非系统字体使用自定义 View hack。无论如何,我希望这可以帮助一些像我一样正在寻找这个答案的访问者。

于 2015-09-15T01:04:39.423 回答