在 Android 中放置一叠可点击的扑克牌
Laying out a stack of clickable playing cards in Android
我正在为 Android 编写一个卡片融合游戏。我在一个 FrameLayout 中的一系列 ImageView 中显示玩家当前未融合的卡片,在另一个 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
我使用这些布局参数切换到 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
我正在为 Android 编写一个卡片融合游戏。我在一个 FrameLayout 中的一系列 ImageView 中显示玩家当前未融合的卡片,在另一个 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
我使用这些布局参数切换到 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