具有水平滚动标题的 HeaderListView
Posted
技术标签:
【中文标题】具有水平滚动标题的 HeaderListView【英文标题】:HeaderListView with Horizontal Scrolling Header 【发布时间】:2021-05-18 21:10:50 【问题描述】:我正在寻找一个像这样的 HeaderListView:http://applidium.github.io/HeaderListView/,但是有一个具有水平滚动能力的标题,它列出了我的列表视图的类别,就像在 uber eats 中它提出的东西一样: 饮料
可乐
精灵
披萨
意大利辣香肠比萨
芝士比萨
在标题中会有标签: 饮料比萨饼
如果您正在查看饮料,饮料会带有下划线,披萨不会带下划线。如果您正在查看比萨饼,比萨饼会加下划线,饮料不会加下划线。您可以向下滚动菜单以查看您想要的内容。有人可以指导我到它在哪里吗?我需要一些java中的东西。
谢谢
【问题讨论】:
【参考方案1】:我想通了。这是回收站视图项目移动的汇编,在一个回收站视图中包含 2 种不同类型的项目,并在回收站视图中导航,例如 uber Eats。
在公共类中 YourNameOfFragment 扩展了 Fragment。我把它放在 onCreateView 方法中
RecyclerView recyclerViewItem;
LinearLayoutManager layoutManager;
TabLayout tabLayout;
List<String> list;
View root;
//You need to have an empty tablayout and a recyclerview in your layout
root = inflater.inflate(R.layout.fragment_your_name_of, container, false);
recyclerViewItem = root.findViewById(R.id.linear_recyclerview);
layoutManager = new LinearLayoutManager(getContext());
tabLayout = root.findViewById(R.id.tabLayout);
//Set up smooth scroller to set scroll position in recycler view
LinearSmoothScroller smoothScroller=new LinearSmoothScroller(getActivity())
@Override
protected int getVerticalSnapPreference()
return LinearSmoothScroller.SNAP_TO_START;
;
//Setup items and tabs
List<FoodItem> items = new ArrayList<FoodItem>();
list = new ArrayList<String>();
items.add(new Header("Header 1"));
TabLayout.Tab tab1 = tabLayout.newTab();
tab1.setText(items.get(items.size()-1));
list.add((String)tab1.getText());
tabLayout.addTab(tab1);
items.add(new Item("Text 1", "Rabble rabble"));
items.add(new Item("Text 2", "Rabble rabble"));
items.add(new Item("Text 3", "Rabble rabble"));
items.add(new Item("Text 4", "Rabble rabble"));
items.add(new Item("Text 5", "Rabble rabble"));
items.add(new Item("Text 6", "Rabble rabble"));
items.add(new Item("Text 7", "Rabble rabble"));
items.add(new Item("Text 8", "Rabble rabble"));
items.add(new Header("Header 2"));
TabLayout.Tab tab2 = tabLayout.newTab();
list.add((String)tab2.getText());
tab2.setText(items.get(items.size()-1).getStr1());
tabLayout.addTab(tab2);
items.add(new Item("Text 5", "Rabble rabble"));
items.add(new Item("Text 6", "Rabble rabble"));
items.add(new Item("Text 7", "Rabble rabble"));
items.add(new Item("Text 8", "Rabble rabble"));
items.add(new Item("Text 5", "Rabble rabble"));
items.add(new Item("Text 6", "Rabble rabble"));
items.add(new Item("Text 7", "Rabble rabble"));
items.add(new Item("Text 8", "Rabble rabble"));
items.add(new Item("Text 5", "Rabble rabble"));
items.add(new Item("Text 6", "Rabble rabble"));
items.add(new Item("Text 7", "Rabble rabble"));
items.add(new Item("Text 8", "Rabble rabble"));
TwoTextArrayAdapter adapter = new TwoTextArrayAdapter(getContext(), items);
recyclerViewItem.setLayoutManager(layoutManager);
recyclerViewItem.setAdapter(adapter);
//Setup the recycler view to be able to move items
ItemTouchHelper.Callback callback = new ItemMoveCallback(adapter);
ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
touchHelper.attachToRecyclerView(recyclerViewItem);
recyclerViewItem.addOnScrollListener(new RecyclerView.OnScrollListener()
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState)
super.onScrollStateChanged(recyclerView, newState);
// Toast.makeText(this, "You clicked " + adapter.getItem(position) + " on row number " + position, Toast.LENGTH_SHORT).show();
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy)
super.onScrolled(recyclerView, dx, dy);
int position = ((LinearLayoutManager)recyclerView.getLayoutManager()).findFirstCompletelyVisibleItemPosition();
if(dy > 0)
//when it scrolls one direction, do this
if(adapter.getItem(position).getType() == FoodItem.TYPE_HEADER)
String item1 = adapter.getItem(position).getStr1();
String item2;
for (int i = 0; i < tabLayout.getTabCount(); i++)
item2 = (String) (tabLayout.getTabAt(i).getText());
if (item1.equals(item2))
tabAutoSelected = 1;
tabLayout.selectTab(tabLayout.getTabAt(i));
break;
else //when it scrolls, the other direction, do this
String header = "";
for (int i = 0; i < adapter.getItemCount(); i++)
if (adapter.getItem(i).getType() == FoodItem.TYPE_HEADER)
header = adapter.getItem(i).getStr1();
if (i == position)
String item2;
for (int y = 0; y < tabLayout.getTabCount(); y++)
item2 = (String) (tabLayout.getTabAt(y).getText());
if (header.equals(item2))
tabAutoSelected = 1;
tabLayout.selectTab(tabLayout.getTabAt(y));
break;
break;
);
//tabLayout listener so that you can click on tabs and it takes you to where you want to go
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener()
@Override
public void onTabSelected(TabLayout.Tab tab)
if(tabAutoSelected == 1)//if tab is selected by scrolling, then reset flag
tabAutoSelected = 0;
else//if tab is selected by clicking then set recycler view to header
for(int y = 0; y < adapter.getItemCount(); y++)
String item1 = adapter.getItem(y).getStr1();
String item2 = (String)tab.getText();
if(item1.equals(item2))
smoothScroller.setTargetPosition(y);
recyclerViewItem.getLayoutManager().startSmoothScroll(smoothScroller);
break;
@Override
public void onTabUnselected(TabLayout.Tab tab)
@Override
public void onTabReselected(TabLayout.Tab tab)
if(tabAutoSelected == 1)//if tab is selected by the scrolling, then reset flag
tabAutoSelected = 0;
else//if tab is selected by clicking, then scroll recycler view to header
for(int y = 0; y < adapter.getItemCount(); y++)
String item1 = adapter.getItem(y).getStr1();
String item2 = (String)tab.getText();
if(item1.equals(item2))
smoothScroller.setTargetPosition(y);
recyclerViewItem.getLayoutManager().startSmoothScroll(smoothScroller);
break;
);
return root;
FoodItem.java
public interface FoodItem
int TYPE_HEADER = 100;
int TYPE_ITEM = 101;
int getType();
String getStr1();
Header.java
public class Header implements FoodItem
// variables and methods
public String str1;
@Override
public int getType()
return FoodItem.TYPE_HEADER;
public Header(String text1)
super();
this.str1 = text1;
public String getStr1()
return str1;
public void setStr1(String str1)
this.str1 = str1;
Item.java
public class Item implements FoodItem
// variables and methods
public String str1;
public String str2;
@Override
public int getType()
return FoodItem.TYPE_ITEM;
public Item(String text1, String text2)
super();
this.str1 = text1;
this.str2 = text2;
public String getStr1()
return str1;
public void setStr1(String str1)
this.str1 = str1;
public String getStr2()
return str2;
public void setStr2(String str2)
this.str2 = str2;
TwoTextArrayAdapter.java
public class TwoTextArrayAdapter extends RecyclerView.Adapter implements ItemTouchHelperAdapter
private List<FoodItem> list;
public TwoTextArrayAdapter(Context context, List<FoodItem> itemViewHolders)
list = itemViewHolders;
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
View itemView;
switch (viewType)
case FoodItem.TYPE_ITEM:
itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_list_item, parent, false);
return new ItemViewHolder(itemView);
case FoodItem.TYPE_HEADER:
itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.header, parent, false);
return new HeaderViewHolder(itemView);
default:
return null;
public FoodItem getItem(int id)
return list.get(id);
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position)
switch (getItemViewType(position))
case FoodItem.TYPE_ITEM:
((ItemViewHolder) holder).bindView(position);
break;
case FoodItem.TYPE_HEADER:
((HeaderViewHolder) holder).bindView(position);
break;
@Override
public int getItemViewType(int position)
return list.get(position).getType();
@Override
public int getItemCount()
if (list == null)
return 0;
else
return list.size();
public void setFoodList(List<? extends FoodItem> FoodList)
if (list == null)
list = new ArrayList<>();
list.clear();
list.addAll(list);
notifyDataSetChanged();
public class ItemViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder
public View view;
public TextView txtViewItem, txtViewItem2;
public ItemViewHolder(@NonNull android.view.View itemView)
super(itemView);
txtViewItem = itemView.findViewById(R.id.list_content1);
txtViewItem2 = itemView.findViewById(R.id.list_content2);
view = itemView;
void bindView(int position)
Item item = (Item) list.get(position);
// bind data to the views
// textView.setText()...
txtViewItem.setText(item.getStr1());
txtViewItem2.setText(item.getStr2());
@Override
public void onItemSelected()
view.setBackgroundColor(Color.LTGRAY);
@Override
public void onItemClear()
view.setBackgroundColor(0);
public class HeaderViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder
public View view;
public TextView txtViewSeparator;
public HeaderViewHolder(@NonNull android.view.View itemView)
super(itemView);
txtViewSeparator = itemView.findViewById(R.id.separator);
view = itemView;
void bindView(int position)
Header header = (Header) list.get(position);
// bind data to the views
// textView.setText()...
txtViewSeparator.setText(header.getStr1());
@Override
public void onItemSelected()
view.setBackgroundColor(Color.LTGRAY);
@Override
public void onItemClear()
view.setBackgroundColor(0);
@Override
public void onItemDismiss(int position)
list.remove(position);
notifyItemRemoved(position);
@Override
public boolean onItemMove(int fromPosition, int toPosition)
//Log.v("", "Log position" + fromPosition + " " + toPosition);
if (fromPosition < list.size() && toPosition < list.size())
if (fromPosition < toPosition)
for (int i = fromPosition; i < toPosition; i++)
Collections.swap(list, i, i + 1);
else
for (int i = fromPosition; i > toPosition; i--)
Collections.swap(list, i, i - 1);
notifyItemMoved(fromPosition, toPosition);
return true;
【讨论】:
以上是关于具有水平滚动标题的 HeaderListView的主要内容,如果未能解决你的问题,请参考以下文章