仅使用一个元素将CardView置于RecyclerView的中心 [英] Center a CardView in a RecyclerView with only one element
问题描述
我正在使用一个RecyclerView,其中包含CardView,TextView和ImageView(每张卡代表一个城市).我在每张卡片上都有一个onClickListener,可将我带到城市中的博物馆列表. (RecyclerView由ArrayList填充). 该列表是由垂直滚动的同一Cardview组成的RecyclerView.
I'm using a RecyclerView that contains CardViews with a TextView and a ImageView (Every card represents a city). I also have a onClickListener on every card that leads me to a list of museum in the city. (The RecyclerView is populated by an ArrayList). The list is a RecyclerView composed by the same Cardview that scrolls vertically.
当一个城市只有一个博物馆时,如何在屏幕中央显示唯一的CardView?
When a city has only one museum, how can I display the unique CardView at the center of the screen?
这是活动xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.bebbo203.mymuseum.MuseumActivity">
<android.support.v7.widget.RecyclerView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/recyclerViewMuseum"
android:scrollbars="vertical"
android:scrollIndicators="none"
android:gravity="center_horizontal"
/>
</RelativeLayout>
这是RecyclerView xml:
And this is the RecyclerView xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
xmlns:card_view="http://schemas.android.com/apk/res-auto">
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="150dp"
android:id="@+id/cardView"
card_view:cardCornerRadius="2dp"
card_view:cardUseCompatPadding="true"
android:gravity="center_horizontal"
android:animateLayoutChanges="true"
>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="150dp"
android:id="@+id/imageViewList"
android:layout_gravity="center_horizontal|top"
android:adjustViewBounds="true"
android:scaleType="centerCrop"/>
<TextView
android:id="@+id/textViewList"
android:layout_width="match_parent"
android:layout_height="150dp"
android:textSize="40sp"
android:textIsSelectable="false"
android:textAlignment="center"
android:gravity="fill"
android:textStyle="bold"
android:layout_weight="1"
android:layout_gravity="center_horizontal|top"/>
</FrameLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>`
感谢您的帮助.
这是MainActivity.城市列表.这里一切都很好.
So this is the MainActivity. A list of Cities. All is good here.
当我点击只有一个博物馆的Parigi时,我想在屏幕中央显示一张卡片视图
When I click on Parigi that has only one museum I wanted to show the single cardview at the center of the screen
(而且,如果可能的话,我想使Cardview从屏幕的中心开始,而不是从顶部开始.就像打开活动时中央Cardview总是在中心.例如,在中心维护另一个的顺序
(And if it's possible i would like to make the cardview starting from the center of the screen, not from the top. Like if the central cardview is always at the center when I open the activity. For example translating NationalGallery at the center mantaining the order of the other)
推荐答案
我已经实现了简单的HelloWorld应用,该应用可显示城市列表并基于其拥有的博物馆数量-显示全尺寸的城市卡片或居中位置,包装后的版本.
I've implemented simple HelloWorld app, which shows list of cities and based on how many museums it has - shows full-sized city-card or the centered, wrapped version of it.
(是的,我不太擅长艺术:-))
(Yes, I'm not exactly good at arts :-) )
这是我的方法.
关键部分是ItemDecoration
:设置适当的项目偏移量,您将获得所需的东西.这是我的操作方式:
The crucial part is ItemDecoration
: set proper items offset and you'll get what you need; Here's how I've done it:
RecyclerView recyclerViewMuseum = (RecyclerView)findViewById(R.id.recyclerViewMuseum);
recyclerViewMuseum.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
recyclerViewMuseum.setAdapter(adapter);
recyclerViewMuseum.addItemDecoration(new RecyclerView.ItemDecoration() {
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
if (view instanceof CityWithOneMuseumCardView) {
int totalWidth = parent.getWidth();
int cardWidth = getResources().getDimensionPixelOffset(R.dimen.small_card_width);
int sidePadding = (totalWidth - cardWidth) / 2;
sidePadding = Math.max(0, sidePadding);
outRect.set(sidePadding, 0, sidePadding, 0);
}
}
});
这是我的模型-City
和Museum
类:
public class Museum {
public String title;
public Museum(String title) {
this.title = title;
}
}
public class City {
public String title;
public int imageRes;
public List<Museum> museums = new ArrayList<>();
public City(String title, int imageRes) {
this.title = title;
this.imageRes = imageRes;
}
}
然后查看:CityWithManyMuseumsCardView
和CityWithOneMuseumCardView
.他们俩都使用helper-interface IItemDisplayer
.
Then Views: CityWithManyMuseumsCardView
and CityWithOneMuseumCardView
. Both of them are using helper-interface IItemDisplayer
.
public class CityWithOneMuseumCardView extends CardView implements IItemDisplayer<City> {
public CityWithOneMuseumCardView(Context context) {
super(context);
LayoutInflater.from(context).inflate(R.layout.one_museum_layout, this);
}
@Override
public void displayItem(City city) {
TextView cityTitleTextView = (TextView)findViewById(R.id.cityTitleTextView);
cityTitleTextView.setText(city.title);
}
}
public class CityWithManyMuseumsCardView extends CardView implements IItemDisplayer<City> {
public CityWithManyMuseumsCardView(Context context) {
super(context);
LayoutInflater.from(context).inflate(R.layout.many_museums_layout, this);
}
@Override
public void displayItem(City city) {
ImageView cityBackgroundImageView = (ImageView)findViewById(R.id.cityBackgroundImageView);
cityBackgroundImageView.setImageResource(city.imageRes);
TextView cityTitleTextView = (TextView)findViewById(R.id.cityTitleTextView);
cityTitleTextView.setText(city.title);
TextView cityNumberOrMuseumsTextView = (TextView)findViewById(R.id.cityNumberOrMuseumsTextView);
cityNumberOrMuseumsTextView.setText(String.valueOf(city.museums.size()));
}
}
public interface IItemDisplayer<TItem> {
public void displayItem(TItem item);
}
及其布局:
<!-- One Museum card -->
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#BB2050AB"
android:layout_width="@dimen/small_card_width"
android:layout_height="200dp">
<TextView
android:background="#AA000000"
android:textColor="#FFFFFF"
android:text="Only one museum available"
android:textSize="16sp"
android:padding="4dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/cityTitleTextView"
android:layout_gravity="bottom"
android:background="#AAFFFFFF"
android:textColor="#000000"
android:textSize="24sp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="48dp" />
</FrameLayout>
<!-- Many museums card -->
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="240dp">
<ImageView
android:id="@+id/cityBackgroundImageView"
android:scaleType="fitXY"
android:layout_width="500dp"
android:layout_height="match_parent" />
<TextView
android:id="@+id/cityNumberOrMuseumsTextView"
android:layout_gravity="top|end"
android:background="#AA000000"
android:textColor="#FFFFFF"
android:textSize="16sp"
android:padding="4dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/cityTitleTextView"
android:layout_gravity="bottom"
android:background="#AA000000"
android:textColor="#FFFFFF"
android:textSize="24sp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="48dp" />
</FrameLayout>
然后我们需要为我们的RecyclerView
创建一个适配器
CityAdapter.java
Then we need to create an adapter for our RecyclerView
CityAdapter.java
public class CityAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
final static int ITEM_TYPE_MANY_MUSEUMS = 0;
final static int ITEM_TYPE_ONE_MUSEUM = 1;
private List<City> items;
public CityAdapter(List<City> items) {
this.items = items;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
switch (viewType) {
case ITEM_TYPE_MANY_MUSEUMS:
return new ViewHolder(new CityWithManyMuseumsCardView(viewGroup.getContext()));
case ITEM_TYPE_ONE_MUSEUM:
return new ViewHolder(new CityWithOneMuseumCardView(viewGroup.getContext()));
default:
throw new IllegalArgumentException(String.format("Unexpected viewType: %d", viewType));
}
}
@Override
public int getItemViewType(int position) {
if (items == null || items.size() < position) {
throw new IllegalArgumentException("Wrong position!");
}
if (items.get(position).museums.size() > 1) {
return ITEM_TYPE_MANY_MUSEUMS;
} else if (items.get(position).museums.size() == 1){
return ITEM_TYPE_ONE_MUSEUM;
}
throw new IllegalArgumentException("Wrong number of museums!");
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((IItemDisplayer<City>) holder.itemView).displayItem(items.get(position));
}
@Override
public int getItemCount() {
return items.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View itemView) {
super(itemView);
}
}
}
我已经将该项目上传到我的保管箱-随时检查出来!希望有帮助.
I've uploaded this project to my dropbox - feel free to check it out! Hope, it helps.
这篇关于仅使用一个元素将CardView置于RecyclerView的中心的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!