Выкладка стопки кликабельных игральных карт в Android

Я пишу карточную игру для Android. Я отображаю текущие несоединенные карты игрока в серии ImageViews в одном FrameLayout и объединенные карты ниже в другом FrameLayout. Я смещаю каждую карту от предыдущей.

Я могу относительно легко выкладывать карты, начиная с левой стороны экрана. Но я бы предпочел, чтобы они были в центре. Вот проблемы:

  • Если я использую layout_width="wrap_content" и layout_gravity="center_horizontal", FrameLayout обрезает результирующий стек ImageView на основе самого большого одиночного ImageView (это задокументировано).
  • Если я использую layout_width="match_parent" и layout_gravity="left" (как в приведенном ниже коде), объединения выглядят нормально, за исключением того, что они не центрированы
  • Как ни странно, хотя я установил layout_gravity="left", первый ImageView позиционируется по центру по горизонтали.

Я программно настроил TranslationX для центрирования, как в фрагменте кода. Но это связано с некоторыми пробами и ошибками и кажется хакерским.

Вопросы:

  1. Любые предложения по лучшему способу сделать все это? (кстати, я начал с LayeredDrawable, но переключился, как только понял, что отдельные рисунки не будут кликабельны).
  2. Я неправильно понимаю роль layout_gravity? Я думал, что это относится к дочерним представлениям, но, похоже, это не имеет никакого эффекта.

Фрагмент макета (соответствующие блоки — два FrameLayout):

<LinearLayout
    android:layout_above="@+id/Play"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/score_and_game"
    android:id="@+id/play_area"
    android:weightSum="4"
    >

    <TextView
        android:id="@+id/game_info_line"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:layout_weight="0.5"
        android:layout_gravity="center_horizontal"/>

    <TextView
        android:id="@+id/info_line"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:text="@string/blank"
        android:gravity="center_vertical|center_horizontal"
        android:layout_weight="0.5"
        android:textStyle="normal"
        android:layout_gravity="center_horizontal"/>

    <FrameLayout
        android:id="@+id/current_cards"
        android:layout_width="match_parent"
        android:layout_weight="1"
        android:layout_height="96dp"
        android:layout_gravity="left">
    </FrameLayout>

    <FrameLayout
        android:id="@+id/current_melds"
        android:layout_width="match_parent"
        android:layout_weight="1"
        android:layout_height="96dp"
        >
    </FrameLayout>


</LinearLayout>

Фрагмент кода для взлома позиционирования:

static final float CARD_OFFSET =30.0f;
static final float ADDITIONAL_MELD_OFFSET = 20.0f;
static final float CARD_WIDTH = 72.0f;
....
//show melds and unmelded as ImageViews
private void showCards(ArrayList<CardList> meldLists, FrameLayout frameLayout) {
    ArrayList<ImageView> cardLayers = new ArrayList<>(Game.MAX_CARDS);
    float xOffset=0f;
    frameLayout.removeAllViews();
    for (CardList cardlist : meldLists) {
        for (Card card : cardlist.getCards()) {
            ImageView iv = new ImageView(this);
            iv.setImageDrawable(card.getDrawable());
            iv.setTranslationX(xOffset);
            iv.bringToFront();
            cardLayers.add(iv);
            xOffset += CARD_OFFSET;
        }
        xOffset += ADDITIONAL_MELD_OFFSET;
    }
    //bit of a hack: we now adjust everything by - 1/2*(width of stacked image) to center it
    // add CARD_WIDTH because the total width of the stacked image is sum(offsets) + CARD_WIDTH
    // subtract CARD_OFFSET and ADDITIONAL_MELD_OFFSET because we added these at the end of the loop (but they're not in the layout)
    xOffset = xOffset - CARD_OFFSET - ADDITIONAL_MELD_OFFSET + CARD_WIDTH;
    if (!cardLayers.isEmpty()) {
        for (ImageView iv : cardLayers) {
            iv.setTranslationX(iv.getTranslationX()-0.5f*xOffset);
            frameLayout.addView(iv);
        }
    }
}//end showCards

person Opus1217    schedule 17.02.2015    source источник


Ответы (1)


Я переключился на RelativeLayout со следующими параметрами макета:

        <RelativeLayout
        android:id="@+id/current_cards"
        android:layout_width="match_parent"
        android:layout_weight="1"
        android:layout_height="96dp"
        android:gravity="center">
    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/current_melds"
        android:layout_width="match_parent"
        android:layout_weight="1"
        android:layout_height="96dp"
        android:gravity="center">
    </RelativeLayout>

и с практически одним и тем же кодом, и это работает, как и ожидалось. Он также позволяет щелкать по отдельным карточкам, как описано здесь

person Opus1217    schedule 18.02.2015