码农知识堂 - 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();
        }
    
    }
    

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

  • 相关阅读:
    Xshell如何连接虚拟机
    基于随机森林实现特征选择降维及回归预测(Matlab代码实现)
    这些大厂笔试题 你都见识(被无情鞭挞)过了吗?—— 瓜子二手车篇
    华为OD 数列描述(100分)【java】A卷+B卷
    【160】相交链表
    web入门之 Promise API
    串口转TCP/IP方案选型
    Xilinx FPGA管脚约束语法规则(UCF和XDC文件)
    好用、可靠有安全的企业局域网文件传输工具
    CH58X/CH57X/V208 Observer(观察者)例程讨论讲解
  • 原文地址:https://blog.csdn.net/lw1389074/article/details/125913989
    • 最新文章
    • 攻防演习之三天拿下官网站群
      数据安全治理学习——前期安全规划和安全管理体系建设
      企业安全 | 企业内一次钓鱼演练准备过程
      内网渗透测试 | Kerberos协议及其部分攻击手法
      0day的产生 | 不懂代码的"代码审计"
      安装scrcpy-client模块av模块异常,环境问题解决方案
      leetcode hot100【LeetCode 279. 完全平方数】java实现
      OpenWrt下安装Mosquitto
      AnatoMask论文汇总
      【AI日记】24.11.01 LangChain、openai api和github copilot
    • 热门文章
    • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
      奉劝各位学弟学妹们,该打造你的技术影响力了!
      五年了,我在 CSDN 的两个一百万。
      Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
      面试官都震惊,你这网络基础可以啊!
      你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
      心情不好的时候,用 Python 画棵樱花树送给自己吧
      通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
      13 万字 C 语言从入门到精通保姆级教程2021 年版
      10行代码集2000张美女图,Python爬虫120例,再上征途
    Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
    正则表达式工具 cron表达式工具 密码生成工具

    京公网安备 11010502049817号