2014-04-03 141 views
1

我一直在面对我编码的自定义视图的问题。基本上,我有一个自定义的视图,处理不同部分的座位,不同的状态。我设法编写它,并且它工作正常。
由于该应用程序有点慢,我决定裁剪图像:而不是采用透明的整个屏幕,它只需要一部分屏幕(我没有做图形)。自定义视图搞乱布局

但由于我裁剪了图像,它们是messing up my layout。我不知道为什么,因为当我用ImageView替换我的自定义视图时,它完全适合!
它看起来像我的看法是忽略“wrap_content”,并超过它所需要的。将该值设置为“match_parent”也不起作用。

我试图再次裁剪我的图片,我以为这是因为它的大小,但事实并非如此。我试图覆盖onMeasure方法,没有改变。我不想硬编码的大小,因为我觉得这是一件坏事。

为什么会发生这种情况,我该如何解决?

这是我的一些代码片段。

fragment_lumbar.xml:

<?xml version="1.0" encoding="utf-8"?> 
<!-- Main screen --> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="@drawable/background_logo"> 

    <!-- Left menu with control buttons --> 

    <RelativeLayout 
     android:id="@+id/lumbar_control" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:padding="61dp"> 

     <ImageButton 
      android:id="@+id/button_arrowup" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_centerHorizontal="true" 
      android:layout_marginTop="40dp" 
      android:background="@drawable/arrowup_button" 
      android:contentDescription="@string/moveup_lumbar" /> 

     <!-- Plus/minus buttons --> 

     <ImageButton 
      android:id="@+id/button_plus" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_below="@id/button_arrowup" 
      android:layout_centerVertical="true" 
      android:background="@drawable/plus_button" 
      android:contentDescription="@string/inflate_lumbar" /> 

     <ImageButton 
      android:id="@+id/button_minus" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_below="@id/button_arrowup" 
      android:layout_toRightOf="@id/button_plus" 
      android:layout_marginLeft="90dp" 
      android:background="@drawable/minus_button" 
      android:contentDescription="@string/deflate_back" /> 

     <!-- Arrown down button --> 

     <ImageButton 
      android:id="@+id/button_arrowdown" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_below="@id/button_plus" 
      android:layout_centerHorizontal="true" 
      android:background="@drawable/arrowdown_button" 
      android:contentDescription="@string/movedown_lumbar" /> 

     <!-- Home button --> 


    </RelativeLayout> 

    <!-- Right panel --> 

    <!-- Screen --> 

    <FrameLayout 
     android:id="@+id/center_frame" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginLeft="20dp" 
     android:layout_marginTop="7dp" 
     android:layout_toRightOf="@id/lumbar_control" 
     android:background="@drawable/screen" > 

     <TextView 
     android:id="@+id/text_state" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_alignParentLeft="true" 
     android:layout_margin="10dp" 
     android:textSize="32sp" 
     android:gravity="center" 
     android:textColor="@color/white" 
     android:text="hello"/> 

     <!-- Seat screen --> 
     <ImageView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:id="@+id/seat" 
      android:src="@drawable/lumbar_control_seat"/> 

     <com.SeatStateView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:background="@drawable/lumbar_seat_state" 
      android:id="@+id/lumbar_seat_state" /> 

    </FrameLayout> 

    <!-- Home button --> 
    <Button 
     android:id="@+id/button_home" 
     android:layout_width="332dp" 
     android:layout_height="44dp" 
     android:layout_centerHorizontal="true" 
     android:background="@android:color/transparent" 
     android:layout_alignParentBottom="true" 
     android:contentDescription="@string/home_button"/> 
</RelativeLayout> 

lumbar_seat_state:

<?xml version="1.0" encoding="utf-8"?> 
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > 
    <item android:drawable="@drawable/lumbar_seat_state_1" /> 
    <item android:drawable="@drawable/lumbar_seat_state_2" /> 
    <item android:drawable="@drawable/lumbar_seat_state_3" /> 
</layer-list> 

lumbar_seat_state_1:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res/com"> 

    <item android:drawable="@drawable/lumbar_inflate_1" 
     app:state_inflating="true" /> 
    <item android:drawable="@drawable/lumbar_deflate_1" 
     app:state_deflating="true" /> 
    <item android:drawable="@drawable/lumbar_idle_1" /> 
</selector> 

SeatStateView.java:

public class SeatStateView extends View { 

    /* Custom states */ 
    private static final int[] INFLATING_STATE_SET = { 
     R.attr.state_inflating 
    }; 

    private static final int[] DEFLATING_STATE_SET = { 
     R.attr.state_deflating 
    }; 

    private static final int[] HEATING_STATE_SET = { 
     R.attr.state_heating 
    }; 

    private static final int[] COOLING_STATE_SET = { 
     R.attr.state_cooling 
    }; 

    /* Inflate/Deflate state */ 
    private boolean isInflating = false; 
    private boolean isDeflating = false; 

    /* Heating state */ 
    private boolean isHeating = false; 
    private boolean isCooling = false; 

    public SeatStateView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    // Overrides the onCreateDrawable to add our custom states 
    @Override 
    protected int[] onCreateDrawableState(int extraSpace) { 
     final int[] drawableState = super.onCreateDrawableState(extraSpace + 2); 

     // Checking the states 
     if(isInflating) { 
      mergeDrawableStates(drawableState, INFLATING_STATE_SET); 
     } 

     if(isDeflating) { 
      mergeDrawableStates(drawableState, DEFLATING_STATE_SET); 
     } 

     if(isHeating) { 
      mergeDrawableStates(drawableState, HEATING_STATE_SET); 
     } 

     if(isCooling) { 
      mergeDrawableStates(drawableState, COOLING_STATE_SET); 
     } 

     return drawableState; 
    } 

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

     int parentWidth = MeasureSpec.getSize(widthMeasureSpec); 
     int parentHeight = MeasureSpec.getSize(heightMeasureSpec); 
     this.setMeasuredDimension(parentWidth, parentHeight); 
    } 

    /** 
    * Clears all the states and set to idle. 
    */ 

    public void setIdle() { 
     isInflating = isDeflating = false; 

     // Refresh view 
     refreshDrawableState(); 
    } 

    public void setInflating(boolean state) { 
     if(isInflating != state) { 
      // Update all the states 
      isInflating = state; 

      if(isInflating) { 
       isDeflating = false; 
      } 

      // Refresh view 
      refreshDrawableState(); 
     } 
    } 

    public void setDeflating(boolean state) { 
     if(isDeflating != state) { 
      // Update all the states 
      isDeflating = state; 

      if(isDeflating) { 
       isInflating = false; 
      } 

      // Refresh view 
      refreshDrawableState(); 
     } 
    } 

    public void setHeating(boolean state) { 
     if(isHeating != state) { 
      isHeating = state; 

      if(state) { 
       isCooling = false; 
      } 

      // Refresh view 
      refreshDrawableState(); 
     } 
    } 

    public void setCooling(boolean state) { 
     if(isCooling != state) { 
      isCooling = state; 

      if(state) { 
       isHeating = false; 
      } 

      // Refresh view 
      refreshDrawableState(); 
     } 
    } 
} 
+0

欢迎来到Stack Overflow! – AJMansfield

回答

0

好,刚才搜索了。发现我没有正确覆盖我的onMeasure方法。这是我的新的实现,如果有人绊倒在这个问题:

SeatStateView.java:

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

    // Background image’s size 
    int desiredWidth = getBackground().getIntrinsicWidth(); 
    int desiredHeight = getBackground().getIntrinsicHeight(); 

    int widthMode = MeasureSpec.getMode(widthMeasureSpec); 
    int widthSize = MeasureSpec.getSize(widthMeasureSpec); 
    int heightMode = MeasureSpec.getMode(heightMeasureSpec); 
    int heightSize = MeasureSpec.getSize(heightMeasureSpec); 

    // Final size 
    int width, height; 

    // Set width depending on mode 
    if(widthMode == MeasureSpec.EXACTLY) { 
     width = widthSize; 
    } 
    else if(widthMode == MeasureSpec.AT_MOST) { 
     width = Math.min(desiredWidth, widthSize); 
    } 
    else { 
     width = desiredWidth; 
    } 

    // Set height depending on mode 
    if(heightMode == MeasureSpec.EXACTLY) { 
     height = heightSize; 
    } 
    else if(widthMode == MeasureSpec.AT_MOST) { 
     height = Math.min(desiredHeight, heightSize); 
    } 
    else { 
     height = desiredHeight; 
    } 

    // Finally, set dimension 
    setMeasuredDimension(width, height); 
} 

详情请查看此页:onMeasure custom view explanation

对不起,打扰你了。