我正在开发一个很大程度上依赖于RecyclerView使用的应用程序。
我真的需要知道如何对不同的项目布局使用相同的RecyclerView。布局的一个例子是:
1)具有名称和描述的列表项
2)带有图像和名称的列表项
您可以看到它们相似,但布局略有变化。
提前致谢!
答案 0 :(得分:5)
由于xml中的recyclerview项目并不依赖于您将在其中充气的项目类型,因此您可以继续使用相同的回收站视图布局文件来存储这三个片段。
对于适配器,您的列表似乎是同类的(即单一类型的视图项)。最好的是每种情况下使用3种不同的适配器。您可以自定义构造函数,根据您的方便为每种适配器添加自定义帮助程序方法。
现在,如果您有异构列表,则必须覆盖适配器中的getItemViewType()
,并在onCreateViewHolder()
和onBindViewHolder()
希望这有帮助! :)
答案 1 :(得分:4)
我遇到了类似的情况,这是我所遵循的模型。
首先,片段布局文件。
片段布局文件不会改变所有3个片段(基本上它类似于列表片段),所以我为列表片段创建了一个模板文件。
list_fragment_template.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
现在片段代码:
在我的情况下,所有3个片段都做了几乎相同的事情(获得回收者视图,获取适配器,回收器视图装饰和更多操作等)。
创建了一个AbstrctFragment,它扩展了片段并覆盖onCreate onAttach onDestroy等。由于只有数据的类型为recyclerview消耗,并且将数据推送到recycelrview的适配器将针对每个片段进行更改,因此需要为getAdapter创建一个抽象函数并对数据进行模板化。这三个片段中的每一个都将来自此AbstractFragment。
public abstract class AbstractFragment<E> extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.template_list_fragment, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.list);
// get adapter to show item list
// and fetch data.
mRecyclerAdapter = getAdapter();
mRecyclerView.setAdapter(mRecyclerAdapter);
// show it as vertical list
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
// add seperator between list items.
mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));
return view;
}
... onAttach onDetach以及每个片段的常见成员函数和成员变量。
现在 RecyclerView布局文件。由于它们的布局不同,显然它们必须不同。
RecyclerViewAdapters :这里常见的代码是成员声明,CreateViewHolder(这里只有布局名称更改,所有代码都相同)以及所有这些适配器共享的任何其他功能。 (比如过滤列表项)。
类似于我们对片段的处理方式,你可以将它保存在AbstractRecyclerViewAdapter中,并将bindViewholder等作为抽象函数,并有3个不同的recyclerAdapter,它们将从这个AbstractRecyclerViewAdapter派生出来。
答案 2 :(得分:1)
为时已晚,但可能对有需要的开发人员有所帮助 您的适配器应如下所示,您也可以使用此示例添加页眉和页脚
// Adding to adapter as gridview when grid button clicked
private void setProductGridAdapter() {
mListViewTab.setVisibility(View.VISIBLE);
mGridViewTab.setVisibility(View.INVISIBLE);
mSampleAdapter = new SampleAdapter(YourActicity.this,
yourlist,R.layout.item_product_grid);
mRecyclerView.setAdapter(mSampleAdapter);
mRecyclerView.setHasFixedSize(true);
final GridLayoutManager layoutManager = new GridLayoutManager(getActivity(),
2, //number of columns
LinearLayoutManager.VERTICAL, // orientation
false); //reverse layout
mRecyclerView.setLayoutManager(layoutManager);
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
// to show header and footer in full row
if(position==0 || position==(yourlist.size()+1))
return layoutManager.getSpanCount();
else
return 1;
}
});
mRecyclerView.scrollToPosition(AppController.currentPosition);
mSampleAdapter.notifyDataSetChanged();
// Scroll listener for RecyclerView to call load more products
mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
int visibleItemCount = layoutManager.getChildCount();
int totalItemCount = layoutManager.getItemCount();
int firstVisibleItem = layoutManager.findFirstVisibleItemPosition();
int lastInScreen = firstVisibleItem + visibleItemCount;
if ((lastInScreen >= totalItemCount) && !isLoading) {
//last item
// do something after last item like load more code or
// show No more items string
mSampleAdapter.setFooterData("NO More Items",View.INVISIBLE);
}
AppController.currentPosition = firstVisibleItem;
}
});
}
// Adding to adapter as listview when list button clicked
private void setProductListAdapter() {
mListViewTab.setVisibility(View.INVISIBLE);
mGridViewTab.setVisibility(View.VISIBLE);
mSampleAdapter = new SampleAdapter(YourActicity.this, yourlist,R.layout.item_product_list);
mRecyclerView.setAdapter(mSampleAdapter);
mRecyclerView.setHasFixedSize(true);
final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(),
LinearLayoutManager.VERTICAL, // orientation
false); //reverse layout
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.scrollToPosition(AppController.currentPosition);
mSampleAdapter.notifyDataSetChanged();
// Scroll listener for RecyclerView to call load more products
mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
int visibleItemCount = layoutManager.getChildCount();
int totalItemCount = layoutManager.getItemCount();
int firstVisibleItem = layoutManager.findFirstVisibleItemPosition();
int lastInScreen = firstVisibleItem + visibleItemCount;
if ((lastInScreen >= totalItemCount) && !isLoading) {
//last item
// do something after last item like load more code or
// show No more items string
mSampleAdapter.setFooterData("NO MOre Items",View.INVISIBLE);
}
AppController.currentPosition = firstVisibleItem;
}
});
}
在您的活动中
UITableView
并且您的活动必须在activity中实现SampleAdapterInterface以从适配器获取回调。 将按钮从网格切换到列表时调用这些方法,反之亦然
答案 3 :(得分:-1)
//To setViewType maybe is a solution for you.Sample below:
private static final int TYPE_DESC = 0;
private static final int TYPE_IMAGE = TYPE_DESC + 1;
private static final int TYPE_THREE_TEXT = TYPE_IMAGE + 1;
public int getItemViewType(int position) {
int type = super.getItemViewType(position);
try
{
type = Integer.parseInt(data.get(position).get("type"));
} catch (Exception e)
{
e.printStackTrace();
}
return type;
}
public int getViewTypeCount() {
return 3;
}
public View getView(int position, View convertView, ViewGroup parent) {
int type = TYPE_DESC;
try
{
type = Integer.parseInt(data.get(position).get("type"));
} catch (Exception e)
{
e.printStackTrace();
}
ViewHolder holder = null;
if (convertView == null)
{
System.out.println("getView::convertView is null");
holder = new ViewHolder();
switch (type)
{
case TYPE_DESC:
convertView = View.inflate(getBaseContext(),
R.layout.listitem_1, null);
break;
case TYPE_IMAGE:
convertView = View.inflate(getBaseContext(),
R.layout.listitem_2, null);
break;
case TYPE_THREE_TEXT:
convertView = View.inflate(getBaseContext(),
R.layout.listitem_3, null);
break;
}
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
//TODO
return convertView;
}