6

我已经为 Android 编程了一段时间,但这真的让我很困惑。

所以我有一个带有 textview 的简单 appwidget。如果用户调整小部件的大小,我只是希望该文本视图内的文本字体大小按比例放大/缩小,以便在调整应用程序大小时使文本更大。我尝试了几种解决方案,但一切都失败了:

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

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

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

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

欢迎任何想法?

4

4 回答 4

4

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

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

如果您不使用 aListView或 aGridView在我看来,“缩放”appwidget 组件的最佳方法是您已经提到的方法:使用不同的不可调整大小的 appwidgets。

于 2012-09-02T14:43:55.160 回答
3

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

于 2012-11-23T09:25:29.173 回答
3

结合上面的答案和来自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;
}
于 2016-10-15T14:22:25.233 回答
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();
于 2016-01-23T02:33:10.650 回答