Я пишу карточную игру для 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 для центрирования, как в фрагменте кода. Но это связано с некоторыми пробами и ошибками и кажется хакерским.
Вопросы:
- Любые предложения по лучшему способу сделать все это? (кстати, я начал с LayeredDrawable, но переключился, как только понял, что отдельные рисунки не будут кликабельны).
- Я неправильно понимаю роль 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