仅使用一个元素将CardView置于RecyclerView的中心 [英] Center a CardView in a RecyclerView with only one element

查看:54
本文介绍了仅使用一个元素将CardView置于RecyclerView的中心的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个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);
            }
        }
    });

这是我的模型-CityMuseum类:

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;
    }
}

然后查看:CityWithManyMuseumsCardViewCityWithOneMuseumCardView.他们俩都使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆