RecyclerView具有固定列和标题,以及可滚动页脚

时间:2015-04-01 16:19:08

标签: android android-recyclerview

我正试图找到一种方法来实现一个体育应用程序的站立表(如NBA游戏时间排名),具有固定的标题,固定的第一列和页脚。我搜索了一下如何获得它,但最好的镜头是这个项目(https://github.com/InQBarna/TableFixHeaders),但它使用自己的视图而不是GridView的Recycler。有谁知道这样的事情或者知道如何从它开始(适配器或LayoutManager)?

修改(添加图片)

initial state

scrolled state showing footer

3 个答案:

答案 0 :(得分:11)

经过测试和搜索后,我自己实施,将ListView与内部HorizontalScrollView相结合。

首先,我扩展HorizontalScrollView报告滚动事件,添加一个监听器:

public class MyHorizontalScrollView extends HorizontalScrollView {

    private OnScrollListener listener;

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (listener != null) listener.onScroll(this, l, t);
    }

    public void setOnScrollListener(OnScrollListener listener) {
        this.listener = listener;
    }

    public interface OnScrollListener {
        void onScroll(HorizontalScrollView view, int x, int y);
    }       
}

然后,我使用LinearLayout创建了我的布局,其中包含我的标题和ListView Activity(或Fragment,如果您需要的话)。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <include
        android:id="@+id/header"
        layout="@layout/header" />

    <ListView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

我的列表中的每个项目都是LinearLayout,其中TextView(固定列)和HorizontalScrollView。标题和行的布局如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <TextView
        style="?android:attr/textAppearanceMedium"
        android:background="#f00"
        android:minWidth="40dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <View
        android:layout_width="1px"
        android:layout_height="match_parent"
        android:background="@android:color/black" />

    <net.rafaeltoledo.example.MyHorizontalScrollView
        android:id="@+id/scroll"
        android:scrollbars="none"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:orientation="horizontal">

            <!-- Childs, or columns -->

        </LinearLayout>

    </net.rafaeltoledo.example.MyHorizontalScrollView>

</LinearLayout>

诀窍是在EventBus(我用GreenRobot's之一)的帮助下滚动所有内容以触发水平滚动事件并将所有滚动条移动为一个。我的事件对象包含来自侦听器类的相同数据(也许我可以使用侦听器对象本身?)

public static class Event {

    private final int x;
    private final int y;
    private final HorizontalScrollView view;

    public Event(HorizontalScrollView view, int x, int y) {
        this.x = x;
        this.y = y;
        this.view = view;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public HorizontalScrollView getView() {
        return view;
    }
}

列表适配器类接收要在每个项目的HorizontalScrollView中设置的侦听器。

public static class Adapter extends BaseAdapter {

    private final Context context;
    private MyHorizontalScrollView.OnScrollListener listener;

    public Adapter(Context context, MyHorizontalScrollView.OnScrollListener listener) {
        this.context = context;
        this.listener = listener;
    }

    @Override
    public int getCount() {
        return 30;
    }

    @Override
    public Object getItem(int position) {
        return new Object();
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.header, parent, false);
            MyHorizontalScrollView scroll = (MyHorizontalScrollView) convertView.findViewById(R.id.scroll);
            scroll.setOnScrollListener(listener);
        }
        return convertView;
    }

    public Context getContext() {
        return context;
    }
}

在继续之前,我向EventBus注册了MyHorizontalScrollView,为每个版本的构造函数添加了EventBus.getDefault().register(this),并为其添加了接收方法:

public void onEventMainThread(MainActivity.Event event) {
    if (!event.getView().equals(this)) scrollTo(event.getX(), event.getY());
}

将滚动到收到的位置,如果它本身没有触发滚动事件。

最后,我在onCreate()的{​​{1}}方法中设置了所有内容:

Activity

(请忽略一些奇怪的色彩,这是为了更好地查看正在发生的事情)。

ta-daa,这是理想的结果!

final result

答案 1 :(得分:2)

您可以实现如下布局:

<LinearLayout
    ...
    android:orientation="vertical">

    <TextView 
        ... />

    <com.example.TableHeaderView 
        ... />

    <RecyclerView 
        ... />

</LinearLayout>

只有RecyclerView会滚动,标题文字视图和表格标题会显示在屏幕顶部。

答案 2 :(得分:1)

根据您的图片,我建议您考虑使用StickyGridHeaders等库。它扩展了GridView,并且可以自定义标题&#39;视图。

备选方案是StickyListHeadersHeaderListView,但更多关注ListView

修改

在进一步调查中,提供的示例in this tutorial似乎符合您的要求