码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • Fragment中使用ViewPager滑动浏览页面


    在开发中有时会遇到需要在fragment使用viewPager滑动,使用tablayout + viewPager也好,RecyclerView + ViewPager也好,达到目的就行。

    我这里使用的是RecyclerView + ViewPager,达到在fragment中滑动浏览页面新闻,开撸

    newFragment布局

    
        
        
        
            
            
        
    
    

    准备CenterLayoutManager,这是RecyclerView在点击item时会滑动到中心位置

    public class CenterLayoutManager extends LinearLayoutManager {
    
        static int lastPosition = 0;
        static int targetPosition = 0;
    
        public CenterLayoutManager(Context context, int orientation, boolean reverseLayout) {
            super(context, orientation, reverseLayout);
        }
    
        @Override
        public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
            CenterSmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext());
            smoothScroller.setTargetPosition(position);
            startSmoothScroll(smoothScroller);
        }
    
        public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int lastPosition, int position) {
            CenterLayoutManager.lastPosition = lastPosition;
            CenterLayoutManager.targetPosition = position;
            smoothScrollToPosition(recyclerView, state, position);
        }
    
        public static class CenterSmoothScroller extends LinearSmoothScroller {
            private static float duration = 200f;
    
            public CenterSmoothScroller(Context context) {
                super(context);
            }
    
            @Override
            public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
                return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
            }
    
            @Override
            protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
                float newDuration = duration / (Math.abs(targetPosition - lastPosition));
                return newDuration / displayMetrics.densityDpi;
            }
    
            @Override
            protected int calculateTimeForScrolling(int dx) {
                return super.calculateTimeForScrolling(dx);
            }
        }
    }

    WrapLinearLayoutManager,这个具体是RecyclerView 界面在展示的时候出现下标越界的问题,但具体真的没什么用,RecyclerView出现下标越界的问题时主要是list.clear()后直接list.addAll,暂时找到的解决方法是list.clear之后也需要adapternotifyDataSetChanged

    public class WrapLinearLayoutManager extends LinearLayoutManager {
        public WrapLinearLayoutManager(Context context) {
            super(context);
        }
    
        public WrapLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
            super(context, orientation, reverseLayout);
        }
    
        public WrapLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
        }
    
        @Override
        public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
            try {
                super.onLayoutChildren(recycler, state);
            } catch (IndexOutOfBoundsException e) {
                e.printStackTrace();
            }
        }
    }
    

    再准备一个继承View的类,作为添加到viewPager中的内容

    public class HomeNewPagerDataView extends LinearLayout {
    
        private Context context;
        private LayoutInflater inflater;
        private View view;
    
        private RecyclerView homePagerRecView;
        private List homeListData;
        private HomeFragmentNewAdapter homeListAdapter;
    
        private String uId, code;
    
        public HomeNewPagerDataView(Context context) {
            super(context);
            this.context = context;
            inflater = LayoutInflater.from(context);
            init();
        }
    
        private void init(){
            view = inflater.inflate(R.layout.item_home_new_pager, this);
            homeListData = new ArrayList<>();
            homePagerRecView.setLayoutManager(new WrapLinearLayoutManager(context, RecyclerView.VERTICAL, false));
            homeListAdapter = new HomeFragmentNewAdapter(context, homeListData);
            homePagerRecView.setAdapter(homeListAdapter);
        }
    
        public void getData(){
            homeListData.add(new HomeNewTitleTestBean());
            homeListAdapter.notifyDataSetChanged();
        }
        //动态设置一些数据
        public void setLinkData(String uId, String code){
            this.uId = uId;
            this.code = code;
        }
    
    }

    写HomeNewPagerAdapter

    public class HomeNewPagerAdapter extends androidx.viewpager.widget.PagerAdapter {
    
        private List viewList;
    
        public HomeNewPagerAdapter(List viewList) {
            this.viewList = viewList;
        }
    
        @Override
        public int getCount() {
            return viewList.size();
        }
    
        @Override
        public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
            return view == object;
        }
    
        @Override  //从当前container中删除指定位置(position)的View;
        public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
            container.removeView(viewList.get(position));
        }
    
        @NonNull
        @Override  //第一:将当前视图添加到container中,第二:返回当前View
        public Object instantiateItem(@NonNull ViewGroup container, int position) {
            container.addView(viewList.get(position));
            return viewList.get(position);
        }
    
    }

    newFragment页面代码,关于Base可以参考以前写的,毕竟使用dataBinding真的很方便

    public class HomeFragmentNew extends BaseDataBindingFragment {
    
        private List listBeans;
        private HomeClassifyListAdapter classifyListAdapter;
        private CenterLayoutManager manager;
        private int indexPosition = 0;
    
        private List viewList;
        private HomeNewPagerAdapter pagerAdapter;
        private HomeNewPagerDataView pagerDataView;
    
        @Override
        protected HomeFragmentPresenter createPresenter() {
            return new HomeFragmentPresenter(this);
        }
    
        @Override
        protected int getContentView() {
            return R.layout.fragment_home_new;
        }
    
        @Override
        protected void initView() {
            manager = new CenterLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
            binding.fragHomeTab.setLayoutManager(manager);
        }
    
        @Override
        protected void initData() {
            listBeans = new ArrayList<>();
            classifyListAdapter = new HomeClassifyListAdapter(context, listBeans);
            binding.fragHomeTab.setAdapter(classifyListAdapter);
            presenter.getHomeClassList();
    
            viewList = new ArrayList<>();
            pagerAdapter = new HomeNewPagerAdapter(viewList);
            binding.homeNewViewPager.setAdapter(pagerAdapter);
    
        }
    
        @Override
        protected void initListener() {
            classifyListAdapter.setListener((o, position) -> {
                binding.homeNewViewPager.setCurrentItem(position);
                //注意,这里要先跳转viewPager,再对rec进行刷新,否则会有卡顿感
                new Timer().schedule(new TimerTask() {
                    @Override
                    public void run() {
                        getActivity().runOnUiThread(() -> {
                            setTabPagerView(position);
                        });
                    }
                }, 300);
            });
    
            binding.homeNewViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                @Override
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }
    
                @Override
                public void onPageSelected(int position) {
                    setTabPagerView(position);
                }
    
                @Override
                public void onPageScrollStateChanged(int state) { }
            });
        }
    
        private void setTabPagerView(int position) {
            manager.smoothScrollToPosition(
                    binding.fragHomeTab,
                    new RecyclerView.State(),
                    indexPosition,
                    position);
            if (indexPosition != position) {
                indexPosition = position;
            }
            classifyListAdapter.setSelectedPosition(position);
    
            pagerDataView = (HomeNewPagerDataView) viewList.get(position);
            pagerDataView.getData();
        }
    
    }
    

    基本撸完,在使用中学习,并记录下来,大家一起进步

  • 相关阅读:
    illustrator插件-画板功能开发-全部页面加矩形-垂直两分-水平两分-AI插件
    常见的内置函数、可迭代对象、迭代器对象、异常捕获、异常捕获的用途、生成器对象、模块、绝对导入与相对导入、包的概念、模块
    SSM整合步骤(重点)
    抖音矩阵系统源码,抖音矩阵系统,抖音SEO源码。、
    快应用自定义进度条
    一、MFC介绍
    Android环境配置笔记
    C# 9.0语法标准 “函数指针” 深度解读!
    易基因|干货:手把手教你做RNA m5C甲基化测序分析(RNA-BS)
    C++实现彩色bmp图片转灰度图
  • 原文地址:https://blog.csdn.net/lw1389074/article/details/125913989
    • 最新文章
    • 沪漂五周年了:我越来越迷茫了
      Agentic Skill Routing 实战:别再把所有 Skill 塞进 AI Agent 上下文
      MySQL-Seconds_behind_master的精度误差
      [MAF预定义ChatClient中间件-03]CachingChatClient——利用缓存省钱省时间
      AI的至暗历史:从万众期待到被政府撤资,AI的两次死亡徘徊
      Agent OS :五种驯服不确定性的范式
      PortSwigger SQL注入LAB11
      数据库即时编译JIT
      [Begin]AI Learn Data Day 0
      深度学习进阶(二十七)现代 LLM 的核心架构设计其二:SwiGLU
    • 热门文章
    • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
      奉劝各位学弟学妹们,该打造你的技术影响力了!
      五年了,我在 CSDN 的两个一百万。
      Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
      面试官都震惊,你这网络基础可以啊!
      你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
      心情不好的时候,用 Python 画棵樱花树送给自己吧
      通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
      13 万字 C 语言从入门到精通保姆级教程2021 年版
      10行代码集2000张美女图,Python爬虫120例,再上征途
    小工具 小游戏
    Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

    京公网安备 11010502049817号