2015-04-01 716 views
6

我正试图找到一种方法来为运动应用程序(如NBA游戏时间积分榜)实施一个常规桌面,具有固定标题,固定第一列和页脚。我搜索了一下如何得到它,但最好的拍摄是这个项目(https://github.com/InQBarna/TableFixHeaders),但它使用自己的视图,而不是GridView的Recycler。有没有人知道这样的事情,或知道我可以如何开始(适配器或布局管理器)?具有固定列和标题的RecyclerView,以及可滚动页脚

编辑(添加图像)

initial state

scrolled state showing footer

+0

虽然这是可能的,但这不是微不足道的。我需要这样的解决方案,如果我用RecyclerView构建一个解决方案,我会开源。 – 2015-09-01 19:51:41

回答

10

测试和检索大量后,我自己实施,结合ListView与内部HorizontalScrollView s。

首先,我扩展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,包含我的头和我的Activity(或Fragment一个ListView,如果这是你的需要)。

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

之前继续,我注册MyHorizontalScrollView到EventBus,加入EventBus.getDefault().register(this)构造器的各个版本,并增加了接收器的方法吧:

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

,将滚动到接收的位置,如果不是本身触发了滚动事件。

最后,我设置好的了在我ActivityonCreate()方法的一切:

@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,这里是理想的结果!

final result

+0

您能否请您提供源代码? – 2016-11-23 08:55:56

2

您可以实现像这样的布局:

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

    <TextView 
     ... /> 

    <com.example.TableHeaderView 
     ... /> 

    <RecyclerView 
     ... /> 

</LinearLayout> 

只有RecyclerView将滚动,让你的标题文本视图和表头在屏幕的顶部。

+2

棘手的部分是标题和第一列都应该滚动内容。例如:如果我水平滚动,标题也应滚动以保持列标签符合对齐。垂直滚动相同。 – 2015-04-01 16:49:12

1

从你的图片我会建议考虑使用库,如StickyGridHeaders。它扩展了GridView并且可以有自定义的'标题'视图。

的替代物是StickyListHeadersHeaderListView而更注重的ListView

编辑:

在进一步的调查中,例如提供in this tutorial似乎满足您的要求

+0

是的,我玩了一下(还有SuperSLIM,也就是RecyclerView的库版本),但是我没有找到一种方法来保存头文件,但是第一列中粘贴了这个库。正如我发布的,我发现的最好的解决方案是** TableFixHeaders **,但它不是一个RecyclerView或GridView,是一个完整的自定义视图,所以它不允许我做这么多的定制。 – 2015-04-01 17:00:52

+0

你的意思是第一行吗? Stil不是110%确定你想要滚动什么不是什么 – 2015-04-01 17:04:04

+0

当我水平滚动时,必须保留第一列(与团队名称一致) – 2015-04-01 17:12:14

相关问题