Как изменить размер текста в зависимости от размера виджета в textview в appwidget?
я запрограммировал Android на некоторое время, но это действительно озадачивает меня.
поэтому у меня есть простой appwidget с textview. Я просто хочу, чтобы размер шрифта текста внутри этого textview масштабировался вверх / вниз, если пользователь изменяет размер виджета, чтобы сделать текст больше, если приложение изменяется. Я пробовал несколько решений, но все не удается:
просто используя блок " sp " (масштабированные пиксели) для размера шрифта - это не масштабирует текст при изменении размера виджета (Я тоже этого не ожидал!).
расширение 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;
}