2017-03-11 2 views
1

Es gibt zwei Ansichten in diesem Beispiel. Links ist meine benutzerdefinierte Ansicht und die richtige ist ImageView. ImageView scheint auf dem Vorschaubildschirm korrekt zu zeichnen. Beide Ansichten werden jedoch auf dem laufenden Gerät korrekt gezeichnet.Android benutzerdefinierte Ansicht zeichnen BitmapDrawable im Vorschaubereich falsch rendern

Aber ich möchte es korrekte Vorschau wie ImageView zeigt. Was habe ich falsch gemacht ?

PREVIEW

enter image description here

RUNNING DEVICE

enter image description here

XML

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/activity_main" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="com.apg.mobile.repeatlayout.MainActivity"> 

    <com.my.CustomView 
     android:id="@+id/aa" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="10dp" 
     android:background="@color/colorPrimary" 
     app:src="@drawable/samplebg" /> 

    <ImageView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginStart="5dp" 
     android:layout_marginTop="10dp" 
     android:layout_toEndOf="@+id/aa" 
     android:background="@color/colorPrimary" 
     android:src="@drawable/samplebg" /> 

</RelativeLayout> 

Custom

public class CustomView extends View { 

    private BitmapDrawable bitmapDrawable; 

    public CustomView(Context context) { 
     super(context); 
    } 

    public CustomView(Context context, @Nullable AttributeSet attrs) { 
     super(context, attrs); 
     readAttribute(context, attrs, 0); 
    } 

    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
     readAttribute(context, attrs, defStyleAttr); 
    } 

    @TargetApi(23) 
    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { 
     super(context, attrs, defStyleAttr, defStyleRes); 
     readAttribute(context, attrs, defStyleAttr); 
    } 

    private void readAttribute(Context context, AttributeSet attrs, int defStyleAttr) { 

     TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomView); 
     Drawable drawable = a.getDrawable(R.styleable.CustomView_src); 

     if (drawable == null) 
      throw new NullPointerException("You have to set src first.."); 

     bitmapDrawable = drawableToBitmapDrawable(drawable); 

     a.recycle(); 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 

     int wm, hm; 
     int viewHeightMode = MeasureSpec.getMode(heightMeasureSpec); 
     int viewWidthMode = MeasureSpec.getMode(widthMeasureSpec); 

     Log.d("VIEW WIDTH-MODE", getMode(viewWidthMode)); 
     Log.d("VIEW HEIGHT-MODE", getMode(viewHeightMode)); 

     // 1: find user desired dimension 
     int desiredWidth = measureDesiredSize(widthMeasureSpec, bitmapDrawable.getIntrinsicWidth()); 
     int desiredHeight = measureDesiredSize(heightMeasureSpec, bitmapDrawable.getIntrinsicHeight()); 

     wm = MeasureSpec.makeMeasureSpec(desiredWidth, viewWidthMode); 
     hm = MeasureSpec.makeMeasureSpec(desiredHeight, viewHeightMode); 
     setMeasuredDimension(wm, hm); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 

     bitmapDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); 
     bitmapDrawable.draw(canvas); 
    } 

    private int measureDesiredSize(int measureSpec, int imageSize) { 

     int mode = MeasureSpec.getMode(measureSpec); 
     int size = MeasureSpec.getSize(measureSpec); 

     if (mode == MeasureSpec.EXACTLY) { 
      return size; 
     } else if (mode == MeasureSpec.AT_MOST) { 
      return Math.min(size, imageSize); 
     } else { 
      return imageSize; 
     } 
    } 

    public BitmapDrawable drawableToBitmapDrawable(Drawable drawable) { 

     if (drawable instanceof BitmapDrawable) { 

      return (BitmapDrawable) drawable; 
     } else if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) { 

      // Single color bitmap will be created of 1x1 pixel 
      Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); 
      return new BitmapDrawable(getResources(), bitmap); 
     } else { 

      Bitmap bitmap = Bitmap.createBitmap(
        drawable.getIntrinsicWidth(), 
        drawable.getIntrinsicHeight(), 
        Bitmap.Config.ARGB_8888); 
      return new BitmapDrawable(getResources(), bitmap); 
     } 
    } 


    private String getMode(int mode) { 

     if (MeasureSpec.AT_MOST == mode) { 
      return "AT_MOST"; 
     } else if (MeasureSpec.EXACTLY == mode) { 
      return "EXACTLY"; 
     } else { 
      return "UNSPECIFIED"; 
     } 
    } 
} 

Attribut

<?xml version="1.0" encoding="utf-8"?> 
<resources> 

    <declare-styleable name="CustomView"> 
     <attr name="src" format="reference" />  
    </declare-styleable> 

</resources> 

Ressourcen

Sample drawable Sie es bitte in ziehbar Ordner.

Antwort

0

Ich schaffe es, mein Problem zu lösen, indem ich Breite und Höhe onSizeChanged verwende.

@Override 
    protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld){ 
     super.onSizeChanged(xNew, yNew, xOld, yOld); 

     mViewWidth = xNew; 
     mViewHeight = yNew; 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 

     bitmapDrawable.setBounds(0, 0, mViewWidth, mViewHeight); 
     bitmapDrawable.draw(canvas); 
    } 
Verwandte Themen