Recyclerview水平纸牌效果 [英] Recyclerview horizontal deck of cards effect
问题描述
我正在尝试制作一个简单的纸牌游戏,我需要水平显示躺在桌子上的纸牌,用户可以通过单击选择任意数量的纸牌.理想情况下,使用任何卡时,卡都应比其他卡高一些.加号卡不是完全可见,它们像此一样是部分可见的.我创建了自定义Recyclerview并使用了项装饰器来更改卡片的偏移量.但是,每当我更改偏移量时,甲板的第一张或最后一张卡就会被其他人完全重叠.就像下面的图片一样,
I am trying to make simple card game where I need to show deck of cards laying on the desk horizontally and user can select any number of cards by clicking them. Ideally when use click on any card, card should elevate a bit from other cards. Plus cards are not completely visible, they are partially visible like this. I have created custom Recyclerview and used item decorator to change offset of cards. However whenever I change offset, first or last card of deck is completely overlapped by others. Like following image,
如何在不失去第一张(或最后一张)卡片的情况下正确显示以上效果?另外,当我们点击这些卡时,如何实现这些卡的标高?我尝试使用"setElevation()",但没有效果.如果我能在没有任何第三方库的情况下实现此很好(但是我愿意接受建议).我使用了以下代码,
How to show above effect properly, without loosing first (or last) card? Also how to implement elevation of any of these cards when we click on them ? I tried to use "setElevation()" but it has no effect. It will be nice if I can achieve this without any third party library (however I am open to suggestions.). I used following code,
Game.java
Game.java
public class Game extends AppCompatActivity {
private List<Card> cards = new ArrayList<>();
private RecyclerView.ItemDecoration decoration = new OverlapDecoration();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game);
RecyclerView marketDeck = (RecyclerView) findViewById(R.id.market_deck);
Card item1 = new Card();
item1.setImage(R.color.colorPrimary);
Card item2 = new Card();
item2.setImage(R.color.colorAccent);
cards.add(item1);
cards.add(item2);
cards.add(item1);
cards.add(item2);
cards.add(item1);
CardHolder cardHolder = new CardHolder(cards);
marketDeck.setAdapter(cardHolder);
marketDeck.setLayoutManager(new LinearLayoutManager(getBaseContext(), LinearLayoutManager.HORIZONTAL, false));
marketDeck.addItemDecoration(decoration);
cardHolder.setOnCardClick(new CardHolder.onCardClick() {
@Override
public void onClick(View v) {
v.setElevation(10);
}
});
}
private class OverlapDecoration extends RecyclerView.ItemDecoration {
//Following code from : http://stackoverflow.com/questions/27633454/how-to-overlap-items-in-linearlayoutmanager-recyclerview-like-stacking-cards
private final static int overlap = -100;
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
final int itemPosition = parent.getChildAdapterPosition(view);
if (itemPosition == RecyclerView.NO_POSITION) {
return;
}
outRect.set(overlap, 0, 0, 0);
}
}
}
CardHolder.java
CardHolder.java
public class CardHolder extends RecyclerView.Adapter<CardHolder.CardView> {
private List<Card> cards;
private onCardClick cardClick;
public CardHolder(List<Card> cards) {
this.cards = cards;
}
@Override
public CardView onCreateViewHolder(ViewGroup parent, int viewType) {
return new CardView(LayoutInflater.from(parent.getContext()).inflate(R.layout.card, parent, false));
}
@Override
public void onBindViewHolder(CardView holder, int position) {
Card card = cards.get(position);
holder.icon.setImageResource(card.getImage());
}
@Override
public int getItemCount() {
return cards.size();
}
class CardView extends RecyclerView.ViewHolder {
ImageView icon;
CardView(final View itemView) {
super(itemView);
icon = (ImageView) itemView.findViewById(R.id.card_icon);
icon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cardClick.onClick(v);
}
});
}
}
void setOnCardClick(onCardClick click) {
cardClick = click;
}
public interface onCardClick {
void onClick(View v);
}
}
Card.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5sp">
<ImageView
android:id="@+id/card_icon"
style="@style/CardTheme"
android:contentDescription="@null"
app:srcCompat="@color/colorPrimary" />
</LinearLayout>
game.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.company.someapp.Game">
<android.support.v7.widget.RecyclerView
android:id="@+id/market_deck"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
注意:我保留recyclerview的宽度为"wrap_content",因为卡片的数量是可变的.
推荐答案
通过像下面这样调整第一个元素的边距使其工作,
Got it working by adjusting margin of first element like following,
private class OverlapDecoration extends RecyclerView.ItemDecoration {
//Following code from : http://stackoverflow.com/questions/27633454/how-to-overlap-items-in-linearlayoutmanager-recyclerview-like-stacking-cards
private final static int overlap = -100;
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
final int itemPosition = parent.getChildAdapterPosition(view);
if (itemPosition == 0) {
outRect.set(0, 0, 0, 0);
} else {
outRect.set(overlap, 0, 0, 0);
}
}
}
这篇关于Recyclerview水平纸牌效果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!