具有水平滚动标题的 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的主要内容,如果未能解决你的问题,请参考以下文章

具有水平滚动的嵌套 UIScrollViews

创建具有水平和垂直滚动的 RecyclerView

具有垂直和水平滚动的 Ant Design Table

表格布局可以同时具有水平和垂直滚动视图吗

具有垂直和水平滚动的 Recyclerview

同时具有水平和垂直滚动条的 Android GridView