在 Android 中放置一叠可点击的扑克牌

Laying out a stack of clickable playing cards in Android

我正在为 Android 编写一个卡片融合游戏。我在一个 FrameLayout 中的一系列 ImageView 中显示玩家当前未融合的卡片,在另一个 FrameLayout 中显示下方融合的卡片。我将每张卡片与前一张卡片相抵消。

我可以相对容易地从屏幕左侧开始布置卡片。但我更愿意让它们居中。以下是问题:

我已经以编程方式调整了 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

我使用这些布局参数切换到 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>

并且使用基本相同的代码,并且按预期工作。它还允许单击描述的单个卡片 here