如何根据appwidget中textview中的小部件大小调整文本大小?

时间:2012-09-02 14:24:55

标签: android android-appwidget

我已经对Android编程了一段时间,但这真让我感到困惑。

所以我有一个简单的appwidget和textview。我只是希望文本视图中的文本字体大小在用户调整小部件大小时向上/向下扩展,以便在调整应用程序大小时使文本更大。我尝试了几种解决方案,但一切都失败了:

  1. 只需使用“sp”(缩放像素)单位作为字体大小 - 当窗口小部件大小发生变化时,这不会缩放文本(我也没想到它!)。

  2. 使用我自己的和扩展的onSizeChanged方法扩展TextView。但是你不能在窗口小部件中有基本UI类的后代(文档也说明了这一点)。

  3. 由于没有方法可以获得当前的appWidget大小,我只是被困在这里。

    是的,我知道一个解决方案是创建不同版本的小部件,如1x4和2x4等,但肯定还有另一种方式吗?

    欢迎任何想法?

4 个答案:

答案 0 :(得分:3)

无法根据父级大小自动缩放TextView的文本。解决方法是覆盖TextView的onDraw方法并手动实现缩放。

至于appwidgets:您无法检索可调整大小的appwidget的当前大小,因为它们旨在与ListViewGridView容器一起使用。这些容器将自动管理内容的缩放和间距,并且如果内容无法适应appwidget的当前大小,则可以自行滚动。

如果你没有使用ListViewGridView,在我看来,“扩展”appwidget组件的最佳方法是你已经提到的方法:使用不同的不可调整大小appwidgets。

答案 1 :(得分:3)

您可以调用AppWidgetManager.getAppWidgetOptions(OPTION_APPWIDGET_MAX_WIDTH)获取最大宽度(与窗口小部件的高度相同)并相应地调整文本大小。限制:此方法可从API Level 16

获得

答案 2 :(得分:1)

这是原始的方式,但它有效:

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();

答案 3 :(得分:1)

结合上面的答案和来自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;
}