2016-11-01 3 views
0

Я пытаюсь создать собственный макет «SquareBox» на основе относительной компоновки для размещения ImageView в центре. И этот пользовательский макет всегда будет в квадратном размере (зависит от высоты и ширины ImageView).Центр в родительском не работает для настраиваемого относительного макета

protected void onMeasure(int width, int height) { 
    super.onMeasure(width, height); 
    int measuredWidth = getMeasuredWidth(); 
    int measuredHeight = getMeasuredHeight(); 
    int size; 
    if (measuredWidth > measuredHeight) { 
     size = measuredWidth; 
    } else { 
     size = measuredHeight; 
    } 
    setMeasuredDimension(size, size); 
} 

Вот мой код макета:

<com.example.tools.SquareBox 
     android:id="@+id/square_box" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:gravity="center" 
     android:background="@android:color/darker_gray"> 

    <ImageView 
     android:id="@+id/canvas_image" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_margin="0dp" 
     android:layout_centerInParent="true" 
     android:adjustViewBounds="true" 
     android:scaleType="fitCenter" 
     tools:src="@drawable/demo_image" /> 
</com.example.tools.SquareBox> 

Он работает нормально, но изображение вида не в центре этого пользовательского вида. Я пробовал следующие: -> android: layout_centerInParent = "true" для ImageView.

-> андроид: gravity = "center" для "SquareBox".

-> Добавить CENTER_IN_PARENT программно в ImageView в методе onMeasure SquareBox.

Но ничего не работает. Что мне здесь не хватает?

ответ

0

Я эмулировать поведение квадратного ящика по-другому. Я думаю, что это обходное решение, и это может быть не лучшее решение, но оно работает. Я хотел бы знать лучшее и более чистое решение.

Layout File:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 

    <RelativeLayout 
     android:id="@+id/square_box_holder" 
     android:layout_width="match_parent" 
     android:layout_height="0dp" 
     android:layout_margin="0dp" 
     android:layout_weight="3"> 

     <View 
      android:id="@+id/square_box" 
      android:layout_width="0dp" 
      android:layout_height="0dp" 
      android:layout_centerInParent="true" 
      android:background="@android:color/darker_gray" /> 


     <ImageView 
      android:id="@+id/canvas_image" 
      style="@style/CanvasImageStyle" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_centerInParent="true" 
      android:layout_margin="0dp" 
      android:adjustViewBounds="true" 
      tools:src="@drawable/demo_image2" /> 

    </RelativeLayout> 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="0dp" 
     android:layout_weight="1"> 

    </LinearLayout> 
</LinearLayout> 

код, чтобы изменить вид:

squareImageView.setImageBitmap(getResultBitmap()); 
      squareBoxHolder.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
       @Override 
       public boolean onPreDraw() { 
        squareBoxHolder.getViewTreeObserver().removeOnPreDrawListener(this); 
        Log.i(TAG, "onPreDraw: squareBoxHolder"); 
        squareBoxHolderSize = new Point(squareBoxHolder.getMeasuredWidth(), squareBoxHolder.getMeasuredHeight()); 
        return true; 
       } 
      }); 
      squareImageView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
       @Override 
       public boolean onPreDraw() { 
        squareImageView.getViewTreeObserver().removeOnPreDrawListener(this); 
        Log.i(TAG, "onPreDraw: squareImageView"); 
        int imageWidth = squareImageView.getMeasuredWidth(); 
        int imageHeight = squareImageView.getMeasuredHeight(); 
        int size; 
        ViewGroup.LayoutParams layoutParams = squareImageView.getLayoutParams(); 
        if (imageWidth > imageHeight) { 
         if (imageWidth > squareBoxHolderSize.y) { 
          size = squareBoxHolderSize.y; 
          layoutParams.width = size; 
          squareImageView.setLayoutParams(layoutParams); 
         } else { 
          size = imageWidth; 
         } 
        } else { 
         if (imageHeight > squareBoxHolderSize.x) { 
          size = squareBoxHolderSize.x; 
          layoutParams.height = size; 
          squareImageView.setLayoutParams(layoutParams); 
         } else { 
          size = imageHeight; 
         } 
        } 

        layoutParams = squareBox.getLayoutParams(); 
        layoutParams.height = size; 
        layoutParams.width = size; 
        squareBox.setLayoutParams(layoutParams); 
        return true; 
       } 
      }); 
0

Попробуйте это: - android:layout_gravity="center_horizontal"

+0

Я пытался это тоже. Но не работает. –

0

Изменить макет для этого (изменение layout_width к match_parent):

<com.example.tools.SquareBox 
     android:id="@+id/square_box" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:gravity="center" 
     android:background="@android:color/darker_gray"> 

    <ImageView 
     android:id="@+id/canvas_image" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_margin="0dp" 
     android:layout_centerInParent="true" 
     android:adjustViewBounds="true" 
     android:scaleType="fitCenter" 
     tools:src="@drawable/demo_image" /> 
</com.example.tools.SquareBox> 

и изменить свой собственный макет для этого:

@Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    int widthMode = MeasureSpec.getMode(widthMeasureSpec); 
    int widthSize = MeasureSpec.getSize(widthMeasureSpec); 
    int heightMode = MeasureSpec.getMode(heightMeasureSpec); 
    int heightSize = MeasureSpec.getSize(heightMeasureSpec); 

    int size; 
    if(widthMode == MeasureSpec.EXACTLY && widthSize > 0){ 
     size = widthSize; 
    } 
    else if(heightMode == MeasureSpec.EXACTLY && heightSize > 0){ 
     size = heightSize; 
    } 
    else{ 
     size = widthSize < heightSize ? widthSize : heightSize; 
    } 

    int finalMeasureSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY); 
    super.onMeasure(finalMeasureSpec, finalMeasureSpec); 
    } 
+0

Я пробовал это. Он центрирует изображение в пользовательском представлении. Но после изменения размера пользовательского представления ImageView по-прежнему остается в центре, основанном на предыдущем размере, который заставляет его обрезать. –

Смежные вопросы