Android 具有固定列和页眉以及可滚动页脚的RecyclerView

Android 具有固定列和页眉以及可滚动页脚的RecyclerView,android,android-recyclerview,Android,Android Recyclerview,我正试图找到一种方法来实现一个体育应用程序(如NBA比赛时间排行榜)的站立表,具有固定的页眉、固定的第一列和页脚。我搜索了一下如何获得它,但最好的方法是这个项目(),但它使用自己的视图,而不是GridView的回收器。有人知道这样的东西吗,或者知道我如何开始使用它(适配器或LayoutManager) 编辑(添加图像) 您可以实现如下布局: <LinearLayout ... android:orientation="vertical"> <Text

我正试图找到一种方法来实现一个体育应用程序(如NBA比赛时间排行榜)的站立表,具有固定的页眉、固定的第一列和页脚。我搜索了一下如何获得它,但最好的方法是这个项目(),但它使用自己的视图,而不是GridView的回收器。有人知道这样的东西吗,或者知道我如何开始使用它(适配器或LayoutManager)

编辑(添加图像)


您可以实现如下布局:

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

    <TextView 
        ... />

    <com.example.TableHeaderView 
        ... />

    <RecyclerView 
        ... />

</LinearLayout>


只有RecyclerView将滚动,将标题文本视图和表格标题保留在屏幕顶部。

从您的图像中,我建议您考虑使用以下库:。它扩展了
GridView
,可以有自定义的“header”视图

备选方案是或,但更多地关注
列表视图

编辑:


经过进一步调查,提供的示例似乎符合您的要求

经过大量测试和搜索,我自己实现了,将
列表视图
与内部
水平滚动视图
相结合

首先,我扩展了
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);
    }       
}
然后,我用
线性布局
创建了我的布局,其中包含我的标题和
活动的
列表视图
(或者
片段
,如果需要的话)

诀窍是在
EventBus
的帮助下滚动全部(我使用了其中一个)以触发水平滚动事件并将所有滚动条作为一个整体移动。我的事件对象包含来自listener类的相同数据(也许我可以使用listener对象本身?)

列表适配器类接收要在每个项的
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;
    }
}
在继续之前,我将
MyHorizontalScrollView
注册到EventBus,将
EventBus.getDefault()添加到每个版本的构造函数中。注册(this)
,并将receiver方法添加到其中:

public void onEventMainThread(MainActivity.Event event) {
    if (!event.getView().equals(this)) scrollTo(event.getX(), event.getY());
}
如果触发滚动事件的不是其本身,则将滚动到接收位置

最后,我在我的
活动的
onCreate()方法中设置了所有内容:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.list);

    MyHorizontalScrollView.OnScrollListener listener = new MyHorizontalScrollView.OnScrollListener() {
        @Override
        public void onScroll(HorizontalScrollView view, int x, int y) {
            Log.d("Scroll Event", String.format("Fired! %d %d", x, y));
            EventBus.getDefault().post(new Event(view, x, y));
        }
    };

    ListView listView = (ListView) findViewById(R.id.list);

    ViewGroup header = (ViewGroup) findViewById(R.id.header);
    header.getChildAt(0).setBackgroundColor(Color.WHITE);
    header.setBackgroundColor(Color.BLUE);
    ((MyHorizontalScrollView) header.findViewById(R.id.scroll)).setOnScrollListener(listener);

    listView.setAdapter(new Adapter(this, listener));
    listView.addFooterView(getLayoutInflater().inflate(R.layout.footer, listView, false));
}
(请忽略一些奇怪的颜色,这是为了更好地观察正在发生的事情)

ta daa,这是期望的结果


棘手的部分是,标题和第一栏都应该沿着内容滚动。如果我水平滚动,标题也应该滚动,以保持列标签符合对齐方式。垂直滚动也一样。是的,我玩了一点(还有SuperSLIM,RecyclerViews库的版本),但我没有找到一种方法,不仅保留标题,还保留第一列与此库的粘贴。正如我所发布的,我找到的最好的解决方案是TableFixHeaders,但它不是RecyclerView或GridView,而是一个完整的自定义视图,因此它不允许我对它进行太多自定义。你是说第一行吗?仍然无法110%确定要滚动的内容和不想滚动的内容当我水平滚动时,必须保留第一列(带有团队名称)(就像一个粘性列),尽管这是可能的,但它不是微不足道的。我需要一个这样的解决方案,如果我能用RecyclerView构建一个,我会把它开源。你的解决方案看起来不错。。。我能得到同一台计算机的完整来源吗lankevijayavarma@gmail.com. 非常感谢。
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;
    }
}
public void onEventMainThread(MainActivity.Event event) {
    if (!event.getView().equals(this)) scrollTo(event.getX(), event.getY());
}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.list);

    MyHorizontalScrollView.OnScrollListener listener = new MyHorizontalScrollView.OnScrollListener() {
        @Override
        public void onScroll(HorizontalScrollView view, int x, int y) {
            Log.d("Scroll Event", String.format("Fired! %d %d", x, y));
            EventBus.getDefault().post(new Event(view, x, y));
        }
    };

    ListView listView = (ListView) findViewById(R.id.list);

    ViewGroup header = (ViewGroup) findViewById(R.id.header);
    header.getChildAt(0).setBackgroundColor(Color.WHITE);
    header.setBackgroundColor(Color.BLUE);
    ((MyHorizontalScrollView) header.findViewById(R.id.scroll)).setOnScrollListener(listener);

    listView.setAdapter(new Adapter(this, listener));
    listView.addFooterView(getLayoutInflater().inflate(R.layout.footer, listView, false));
}