Как изменить размер текста в зависимости от размера виджета в textview в appwidget?

я запрограммировал Android на некоторое время, но это действительно озадачивает меня.

поэтому у меня есть простой appwidget с textview. Я просто хочу, чтобы размер шрифта текста внутри этого textview масштабировался вверх / вниз, если пользователь изменяет размер виджета, чтобы сделать текст больше, если приложение изменяется. Я пробовал несколько решений, но все не удается:

  1. просто используя блок " sp " (масштабированные пиксели) для размера шрифта - это не масштабирует текст при изменении размера виджета (Я тоже этого не ожидал!).

  2. расширение TextView с помощью моего собственного и переопределяющего метода onSizeChanged. Но вы не можете иметь потомков основных классов пользовательского интерфейса в виджете (в документации также говорится об этом).

поскольку нет методов даже получить текущий размер appWidget, я просто застрял здесь.

Да, я знаю, что одним из решений является создание разных версий виджета, таких как 1x4 и 2x4 и т. д., Но, конечно, есть по-другому?

любые идеи приветствуются?

4 ответов


невозможно автоматически масштабировать текст TextView на основе родительского размера. Обходным путем было бы переопределить onDraw метод TextView и реализовать масштабирование вручную.

Что касается appwidgets: вы не можете получить текущий размер изменяемого размера appwidget, потому что они предназначены для использования с ListView и GridView контейнеров. Эти контейнеры будут управлять масштабированием и интервалом содержимого автоматически и сделают себя прокручиваемыми, если содержимое не может соответствовать текущему размеру appwidget.

если вы не используете ListView или GridView мне кажется, что лучший способ "масштабировать" компоненты appwidget-это метод, о котором вы уже упоминали: используйте разные не изменяемые appwidgets.


можно назвать AppWidgetManager.getAppWidgetOptions (OPTION_APPWIDGET_MAX_WIDTH) чтобы получить максимальную ширину (так же, как высота виджета) и соответственно настроить размер текста. Ограничение: этот метод доступен с уровня API 16


Это примитивный способ, но он работает:

AppWidgetManager manager = AppWidgetManager.getInstance(this);
ComponentName thisWidget = new ComponentName(this, AppWidget.class);
int[] widgetId = manager.getAppWidgetIds(thisWidget);
Bundle options;
options = manager.getAppWidgetOptions(widgetIds[1]);
int minWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
int maxWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH);
int minHeight = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT);
int maxHeight = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT);
int maxtextLen = (maxWidth / currentTextSize) * (maxHeight / currentTextSize);

Boolean isFit = maxtextLen > textInWidgetTextView.length();

объединение ответов выше и прекрасный код СНиП-это от https://stackoverflow.com/a/7875656/6364860, я заставил его работать так:

*Примечание у меня была круглая кнопка с текстом, поэтому мне нужен был только наименьший размер.

@Override
public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions){

    super.onAppWidgetOptionsChanged(context,appWidgetManager,appWidgetId,newOptions);

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        int maxWidth = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH);
        int maxHeight = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT);

        int size = Math.min(maxHeight,maxWidth);
        int pxSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,size,context.getResources().getDisplayMetrics());

        RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget_button);
        float newSize = refitText(context.getString(R.string.button_text),pxSize);

        remoteViews.setTextViewTextSize(R.id.widget_text, TypedValue.COMPLEX_UNIT_PX,newSize);

        appWidgetManager.updateAppWidget(appWidgetId,remoteViews);
    }

}

private float refitText(String text, int textWidth)
{
    if (textWidth <= 0)
        return 0;

    float hi = 100;
    float lo = 2;
    final float threshold = 0.5f; // How close we have to be

    Paint testPaint = new Paint();

    while((hi - lo) > threshold) {
        float size = (hi+lo)/2;
        testPaint.setTextSize(size);
        if(testPaint.measureText(text) >= textWidth)
            hi = size; // too big
        else
            lo = size; // too small
    }
    // Use lo so that we undershoot rather than overshoot
    return lo;
}