Is it possible to scale drawableleft & drawableright in textview?

前端 未结 8 2192
悲&欢浪女
悲&欢浪女 2020-12-14 05:53

I have TextView with drawableLeft & drawableRight in List item. The problem is, whenever the height of TextView is l

相关标签:
8条回答
  • 2020-12-14 06:01

    I solved an equivalent usecase by introducing a ScaleDrawable and overriding its .getIntrisicHeight() so that it is at least the TextView height. The TextView.addOnLayoutChangeListener part, required to rebind the Drawable on a TextView size change works with API11+

    Drawable underlyingDrawable = 
            new BitmapDrawable(context.getResources(), result);
    
    // Wrap to scale up to the TextView height
    final ScaleDrawable scaledLeft = 
            new ScaleDrawable(underlyingDrawable, Gravity.CENTER, 1F, 1F) {
        // Give this drawable a height being at
        // least the TextView height. It will be
        // used by
        // TextView.setCompoundDrawablesWithIntrinsicBounds
        public int getIntrinsicHeight() {
            return Math.max(super.getIntrinsicHeight(), 
                            competitorView.getHeight());
        };
    };
    
    // Set explicitly level else the default value
    // (0) will prevent .draw to effectively draw
    // the underlying Drawable
    scaledLeft.setLevel(10000);
    
    // Set the drawable as a component of the
    // TextView
    competitorView.setCompoundDrawablesWithIntrinsicBounds(
            scaledLeft, null, null, null);
    
    // If the text is changed, we need to
    // re-register the Drawable to recompute the
    // bounds given the new TextView height
    competitorView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
    
        @Override
        public void onLayoutChange(View v, int left, int top, int right, 
                int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
            competitorView.setCompoundDrawablesWithIntrinsicBounds(scaledLeft, null, null, null);
        }
    });
    
    0 讨论(0)
  • 2020-12-14 06:01

    Just make 9-path background repeating this pattern.

    And also it seems it will be better look in case the pattern will be applied to the list, not to individual item.

    0 讨论(0)
  • 2020-12-14 06:02

    Hope this help

    Textview tv = (TextView) findViewById(R.id.tv_dummy)
    int imageResource =  R.mipmap.ic_image;
    Drawable drawable = ContextCompat.getDrawable(context, imageResource);
    int pixelDrawableSize = (int)Math.round(tv.getLineHeight() * 0.7); // Or the percentage you like (0.8, 0.9, etc.)
    drawable.setBounds(0, 0, pixelDrawableSize, pixelDrawableSize); // setBounds(int left, int top, int right, int bottom), in this case, drawable is a square image
    tv.setCompoundDrawables(
     null, //left
     null, //top
     drawable, //right
     null //bottom
    );
    
    0 讨论(0)
  • 2020-12-14 06:11

    I did not found way. But that you show looks like a list of items. Each item would be a LinearLayout horizontal with imagesView from left to right and text in center. The image dimension do a android:scaleType="fitXY" for ajust the size height to the textview height. If you want no deform de image use scaleType="CENTER_INSIDE". http://developer.android.com/reference/android/widget/ImageView.ScaleType.html

    <LinearLayout
         android:layout_width="fill_parent"
         android:id="@+id/HeaderList" 
         android:layout_gravity="top"
         android:layout_height="wrap_content" >  
    
    
         <ImageView
             android:id="@+id/backImg"
             android:layout_width="fill_parent"
             android:layout_height="fill_parent"
             android:layout_centerInParent="true"
             android:adjustViewBounds="true"
             android:background="@color/blancotransless"
             android:src="@drawable/header"
             android:scaleType="fitXY" >
         </ImageView>
    
             <TextView 
                 android:layout_height="wrap_content"
                 android:layout_width="wrap_content" 
                 android:id="@+id/NameText"
                 android:text="The time of prayer" 
                 android:textColor="#FFFFFF"
                 android:textSize="30sp" 
                 android:layout_alignParentLeft="true"
                 android:layout_alignParentTop="true" 
                 android:paddingLeft="4dp"
                 android:paddingTop="4dp" 
                 />
        <ImageView
             android:id="@+id/backImg"
             android:layout_width="fill_parent"
             android:layout_height="fill_parent"
             android:layout_centerInParent="true"
             android:adjustViewBounds="true"
             android:background="@color/blancotransless"
             android:src="@drawable/header"
             android:scaleType="fitXY" >
         </ImageView>
    
    </LinearLayout> 
    
    0 讨论(0)
  • 2020-12-14 06:12

    This might help you out. There are two properties scaleX and scaleY

    The code below will scale down the image and the text with 30%. Therefore you have to increase the font size with that many "sp", so that when it get re-sized (scaled) it would fit the "sp" you prefer.

    Example. If I set the font to 18, then 30% out of 18 is 5.4sp, so roughly, this is the value I am targeting at, because when it gets scaled, it would become 13sp

    <TextView
            android:textSize="18sp"
            android:scaleX="0.7"
            android:scaleY="0.7"
    

    The last thing to do is set the CompundDrawable.

    tview.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.xxx), null, null, null);
    
    0 讨论(0)
  • 2020-12-14 06:14

    I think the cleanest solution would be to override TextView. Here's an example:

    https://gist.github.com/hrules6872/578b52fe90c30c7445a2

    I changed a bit:

    private void resizeCompoundDrawables() {
        Drawable[] drawables = getCompoundDrawables();
        if (compoundDrawableWidth > 0 || compoundDrawableHeight > 0) {
            for (Drawable drawable : drawables) {
                if (drawable == null) continue;
    
                Rect realBounds = drawable.getBounds();
    
                float drawableWidth = realBounds.width();
                if(this.compoundDrawableWidth>0)
                    drawableWidth = this.compoundDrawableWidth;
                float drawableHeight = realBounds.height();
                if(this.compoundDrawableHeight>0)
                    drawableHeight = this.compoundDrawableHeight;
    
                realBounds.right = realBounds.left + Math.round(drawableWidth);
                realBounds.bottom = realBounds.top + Math.round(drawableHeight);
    
                drawable.setBounds(realBounds);
            }
        }
        super.setCompoundDrawables(drawables[0], drawables[1], drawables[2], drawables[3]);
    }
    

    This way you can set the size of the drawable but if you care about width/height ratio make it the way suits you.

    Now if you want it to automatically match height of the textview you may also override the TextView's method onSizeChanged:

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        compoundDrawableHeight = h;
        resizeCompoundDrawables();
    }
    

    You my also want to declare sizes for each side, for example leftCompoundDrawableWidth, rightCompoundDrawableWidth and so on.

    Note that it does not work with a Shape as drawable. Sounds like TextView only accepts it if it has the size attributes, that way one can implement it by updating the size of the shapedrawable using setSize or setIntrinsicWidth or ... Not tested.

    0 讨论(0)
提交回复
热议问题