2012-09-02 48 views
6

我已經編程了一段時間的Android,但這真讓我感到困惑。如何根據appwidget中的文本視圖中的小部件大小調整文本大小?

所以我有一個簡單的appwidget與textview。如果用戶調整窗口小部件的大小,我只是希望文本視圖中的文本字體大小可以向上/向下縮放,以便在應用調整大小時使文本更大。我已經嘗試了幾種解決方案,但都失敗:

  1. 只需用字體大小的「SP」(縮放的像素)單元 - 這並不縮放文本時,小部件尺寸的變化(我沒想到它也爲好!)。

  2. 用我自己的擴展TextView和重寫的onSizeChanged方法。但是你不能在小部件中擁有基本UI類的後代(文檔也說明了這一點)。

由於沒有方法可以獲得當前appWidget的大小,所以我只是簡單地卡在這裏。

是的,我知道一種解決方案是創建不同版本的小部件,如1x4和2x4等,但肯定還有另一種方式?

歡迎任何想法?

+0

作爲對後來讀者的一個注意事項,我可以說API16+是可以做到的。有一個你可以在你的widget中覆蓋的回調方法:onAppWidgetOptionsChanged,並且從這個方法中你可以得到最大寬度和高度(如下面的一些指出)。但是在API 16之下,調整大小並不容易。 – zaifrun

回答

3

無法根據父大小自動縮放TextView的文本。解決方法是重寫TextView的onDraw方法並手動實施縮放。

至於appwidgets:您無法檢索可調整大小的appwidget的當前大小,因爲它們旨在用於ListViewGridView容器。這些容器將自動管理內容的縮放和間距,並且如果內容不適合appwidget的當前大小,它們將自動滾動。

如果您不使用ListViewGridView在我看來,「縮放」appwidget組件的最佳方法是您已經提到的方法:使用不同的不可調整大小的appwidgets。

+0

就像我說過的,擴展TextView和重寫onDraw的解決方法不適用於appwidgets,因爲文檔中也說明了這一點。也許我可以把TextView放在一個GridView中,它會工作嗎? – zaifrun

+0

將TextView設置爲fill_parent的一行和一列的'GridView'可以工作。如果不是這樣,你應該使用不同大小的不可調整大小的appwidgets。 –

+0

我無法使用gridview進行工作。我想唯一的方法是有幾個不同的不可調整大小的appwidgets(這似乎是其他人的做法)。那麼,希望至少其他人可以從我的問題中受益,並節省時間! – zaifrun

3

您可以撥打AppWidgetManager.getAppWidgetOptions(OPTION_APPWIDGET_MAX_WIDTH)以獲取最大寬度(與小部件高度相同的方式)並相應地調整文本大小。限制:此方法可從API級別16

+1

這個工作正常,雖然不同的發射器會通過稍微不同的值(dp vs. px)等等,所以正確的做法有些雜亂。 –

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(); 
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; 
} 
相關問題