2012-04-01 5 views
6

私は、Androidとの奇妙な問題に捕まってしまったが、集中している画像やテキストを持つボタンを作成する方法 - 私はこのようなボタンが欲しい:アンドロイド:両方

|-----------------------------------------------------------------------| 
|     [icon] <5px> [text text text]      | 
|-----------------------------------------------------------------------| 

とグループを( [アイコン] < 5px> [テキストテキストテキスト])は中央揃えにしてください。アイコンとテキストの間に配置するパディングのプレースホルダとして5pxが使用されていることに注意してください。

バックグラウンドを設定したり私は別の背景を持っているからです)、アンドロイド:drawableLeftプロパティを使ってアイコンを設定します。

しかし、setCompoundDrawablesWithIntrinsicBoundsメソッドのドキュメントが少し誤解を招く(see here)のように見えます。それは、イメージが、真でないTEXTの左/右/上/下の面に置かれていることを示します。アイコンは、ボタンの対応する面に配置されます。たとえば、次のアンドロイドの設定

:drawableLeftプロパティは、最も左の位置にアイコンを置き、(重心で)私にこれを取得します。

|-----------------------------------------------------------------------| 
| [icon]      [text text text]       | 
|-----------------------------------------------------------------------| 

またはこの(LEFT重力で):

|-----------------------------------------------------------------------| 
| [icon] [text text text]            | 
|-----------------------------------------------------------------------| 

の両方が、私はこのようになります回避策を見つけた地獄:(

として醜いです

public static void applyTextOffset(Button button, int buttonWidth) { 
    int textWidth = (int) button.getPaint().measureText(button.getText().toString()); 
    int padding = (buttonWidth/2) - ((textWidth/2) + Constants.ICON_WIDTH + Constants.ICON_TO_TEXT_PADDING); 
    button.setPadding(padding, 0, 0, 0); 
    button.setCompoundDrawablePadding(-padding); 
} 

そして、それは多かれ少なかれ動作しますが、私は次のような理由から、私の好みに合わせてそれを見つけることはありませんが:

  • それはボタンの幅を知ることが必要です。自動サイズのボタンでは、実際のレイアウトが完了するまで認識されません。レンダリング後に実際の幅を知るためにリスナーを使用することをおすすめしますが、これはコードを非常に複雑にします。
  • 私はAndroidのレイアウトエンジンからレイアウトの責任を引き継いだような気がし

が、よりエレガントな解決策ではないですか?

+0

ような何か希望あなたはあなたの問題を解決し – Ishu

答えて

10

この効果を得るには、次のButtonサブクラスを使用できます。

  1. このクラスをプロジェクトに貼り付け、必要に応じてパッケージ名を微調整します。
package com.phillipcalvin.iconbutton; 

    import android.content.Context; 
    import android.content.res.TypedArray; 
    import android.graphics.Rect; 
    import android.graphics.Paint; 
    import android.graphics.drawable.Drawable; 
    import android.util.AttributeSet; 
    import android.widget.Button; 

    public class IconButton extends Button { 
     protected int drawableWidth; 
     protected DrawablePositions drawablePosition; 
     protected int iconPadding; 

     // Cached to prevent allocation during onLayout 
     Rect bounds; 

     private enum DrawablePositions { 
     NONE, 
     LEFT, 
     RIGHT 
     } 

     public IconButton(Context context) { 
     super(context); 
     bounds = new Rect(); 
     } 

     public IconButton(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     bounds = new Rect(); 
     } 

     public IconButton(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     bounds = new Rect(); 
     } 

     public void setIconPadding(int padding) { 
     iconPadding = padding; 
     requestLayout(); 
     } 

     @Override 
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 
     super.onLayout(changed, left, top, right, bottom); 

     Paint textPaint = getPaint(); 
     String text = getText().toString(); 
     textPaint.getTextBounds(text, 0, text.length(), bounds); 

     int textWidth = bounds.width(); 
     int contentWidth = drawableWidth + iconPadding + textWidth; 

     int contentLeft = (int)((getWidth()/2.0) - (contentWidth/2.0)); 
     setCompoundDrawablePadding(-contentLeft + iconPadding); 
     switch (drawablePosition) { 
     case LEFT: 
      setPadding(contentLeft, 0, 0, 0); 
      break; 
     case RIGHT: 
      setPadding(0, 0, contentLeft, 0); 
      break; 
     default: 
      setPadding(0, 0, 0, 0); 
     } 
     } 

     @Override 
     public void setCompoundDrawablesWithIntrinsicBounds(Drawable left, Drawable top, Drawable right, Drawable bottom) { 
     super.setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom); 
     if (null != left) { 
      drawableWidth = left.getIntrinsicWidth(); 
      drawablePosition = DrawablePositions.LEFT; 
     } else if (null != right) { 
      drawableWidth = right.getIntrinsicWidth(); 
      drawablePosition = DrawablePositions.RIGHT; 
     } else { 
      drawablePosition = DrawablePositions.NONE; 
     } 
     requestLayout(); 
     } 
    } 

2.代わりに、プレーンButtonのこの新しいサブクラスを使用するようにレイアウトを変更します。

<com.phillipcalvin.iconbutton.IconButton 
     android:id="@+id/search" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:drawableLeft="@drawable/search" 
     android:text="@string/search" /> 

3.描画可能とテキストの間のパディングを追加したい場合は、に以下を追加しますあなたの活動のonCreate

// Anywhere after setContentView(...) 
    IconButton button = (IconButton)findViewById(R.id.search); 
    button.setIconPadding(10); 

このサブクラスはまたdrawableRightをサポートしています。複数のドロウアブルをサポートしていません。

あなたがそのようなあなたのレイアウトXMLで直接iconPaddingを指定する機能など多くの機能を、必要な場合、私はlibrary that supports this.

-3

私は日食でこれを試してみましたが、それが何のエラーが噴出していない:

<Button android:id="@+id/test" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:background="@android:color/transparent" > 
<LinearLayout 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:layout_weight="1" 
    android:gravity="center" 
    android:background="@android:color/transparent" > 

    </LinearLayout> 
    </Button> 

はしたがって、私はあなたがボタンの内側に、レイアウト自体に画像とテキストビューを追加し、レイアウトを中央可能性があるとします。

よろしくお願いいたします。

+0

ていたので、それだけは、あなたが完全に右でなかった場合、私は、にゃにゃにゃ言う – Gangnus

+0

水平でなければなりません。 – pouzzler

+0

そしてあなたはそれを垂直に持っています:-) – Gangnus

0

カスタムビューを使用してカスタムボタンを作成することも考えられます。

これは、どこからでも簡単に非常に複雑になる可能性があります。

あなたがする必要があるのは、オーバーライドonDraw()であれば簡単です。複数のビューをレイアウトする必要がある場合は、より複雑になります。

+0

この回答は正しいと思いますが解決策を提供しますが、私はそれをより洗練された解決策にすることはできません。私の指摘は、実際にはテキストとアイコンがsetGravity(CENTER)を呼び出して、それがちょっとした過剰なカスタムコンポーネントを作成するときに中心に置かれるのが常識だということです。 – vap78

0

単純な方法を持っているのLinearLayoutでボタンを作成することです。この

<LinearLayout 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:gravity="center"> 

      <Button 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:drawableLeft="@drawable/ic_left" 
       android:drawablePadding="5dp" 
       android:duplicateParentState="true" 
       android:text="Button text"/> 

     </LinearLayout> 
関連する問題