【CodeSnippet】ViewPager & Fragment

本文围绕Android移动开发,介绍了ViewPager的使用,包括基本使用、设置滑动速度等。还阐述了Fragment的相关内容,如判断显示和隐藏、切换效果、标准写法、懒加载、生命周期以及嵌套使用等,为开发者提供了实用的技巧和方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. ViewPager使用

(1)基本使用

自定义Adapter,继承 PagerAdapter

private class MyAdapter extends PagerAdapter {
    private final int Index_Count = 2;
    private View[] views = new View[Index_Count];
    @Override
    public int getCount() {
        return Index_Count;
    }
    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }
    /**
     * 初始化 View 布局
     *  可以在这里,读取入布局后,
     *  初始化View
     * @param container container
     * @param position 位置
     * @return view
     */
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        if (views[position]==null) {
            View convertView = LayoutInflater.from(container.getContext())
                .inflate(R.layout.single_recycler_layout, null);
            container.addView(convertView);
            views[position] = convertView;
        }
        return views[position];
    }
    /**
     * 销毁UI
     * @param container container
     * @param position pager 标号
     * @param object object
     */
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View) object);
    }
}
复制代码

设置MyAdapter

myAdapter = new MyAdapter();
viewPager.setAdapter(myAdapter);
复制代码
(2)设置 ViewPagerIndicator

JK大神的库

参考大神的Demo吧。

(3)Fragment ViewPager

千万不要像(1)一样重写方法,因为 FragmentPagerAdapter 内部已经做好重写了。

public class MyViewPagerAdapter extends FragmentPagerAdapter {

    private List<Fragment> fragmentList;
    
    public MyViewPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);
        this.fragmentList = fragments;
    }

    @Override
    public int getCount() {
        return fragmentList.size();
    }

    @Override
    public Fragment getItem(int position) {
        return fragmentList.get(position);
    }
}
复制代码
ViewPager viewPager;
List<Fragment> list;
list = new ArrayList<>();
list.add(BlankFragment.newInstance("One"));
list.add(BlankFragment.newInstance("Two"));
list.add(BlankFragment.newInstance("Three"));
MyViewPagerAdapter myAdapter = new MyViewPagerAdapter(getSupportFragmentManager(), list);
viewPager = (ViewPager) findViewById(R.id.view_pager);
viewPager.setAdapter(myAdapter);
复制代码

2. 设置ViewPager的滑动速度

参考

定义Scroller:

Scroller scroller = new Scroller(viewPager.getContext()) {
    private int mDuration = 1500;
    @Override
    public void startScroll(int startX, int startY, int dx, int dy, int duration) {
        super.startScroll(startX, startY, dx, dy, mDuration);
    }
    @Override
    public void startScroll(int startX, int startY, int dx, int dy) {
        super.startScroll(startX, startY, dx, dy, mDuration);
    }
};
复制代码

设置Scroller,因为没有API,需要用反射设置:

try {
    Field field = ViewPager.class.getDeclaredField("mScroller");
    field.setAccessible(true);
    field.set(viewPager, scroller);
} catch (Exception ignored) {
}
复制代码

3. 判断Fragment显示和隐藏

判断fragment显示和隐藏

  • 使用show和hide来显隐的Fragment,那么通过:
@Override
public void onHiddenChanged(boolean hidden) {
    super.onHiddenChanged(hidden);
	if(hidden){
		//TODO now visible to user
	} else {
		//TODO now invisible to user
	}
}
复制代码
  • 在ViewPager中的Fragment,此时候上面的方法不适用
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
	if(isVisibleToUser){
		//TODO now it's visible to user
	} else {
		//TODO now it's invisible to user
	}
}
复制代码

4. Fragment切换效果

参考:Fragment动画切换效果

(1)系统自带
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
fragmentTransaction.setTransition(int transit);
// transit参数说明,标准动画设置好后,在Fragment添加和移除的时候都会有。
//      1. FragmentTransaction.TRANSIT_NONE:无动画
//      2. FragmentTransaction.TRANSIT_FRAGMENT_OPEN:标准的打开动画效果
//      3. FragmentTransaction.TRANSIT_FRAGMENT_CLOSE:标准的关闭动画效果
复制代码
(2)自定义
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.in_from_right, R.anim.out_to_left);
复制代码

5. Fragment点击触发Activity布局或者其他的Fragment

关于Fragment叠加点击穿透的解决方案

原因:Fragment的布局实质是依赖在Activity之上,因为会有事件分发和传递。

解决:

  • XML中给fragment的布局设置,或者在Java代码中设置也可以

     android:clickable="true"
     android:focusable="true"
    复制代码
  • 给布局设置onTouch事件,并返回true,代表拦截此事件。

    view.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return true;     //截断事件的传递
        }
    });
    复制代码

6. Fragment标准写法

Android Studio 新建Fragment模块的时候,示例代码:

public class BlankFragment extends Fragment {
    
    /*声明传入的参数*/
    private static final String ARG_PARAM1 = "param1";
    private String mParam1;
    
    /*监听器*/
    private OnFragmentInteractionListener mListener;
    
    /*必须要一个空的构造方法*/
    public BlankFragment() {}

    /**
     * 使用这个方法进行实例化
     * @param param1 参数
     * @return fragment
     */
    public static BlankFragment newInstance(String param1) {
        BlankFragment fragment = new BlankFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        fragment.setArguments(args);
        return fragment;
    }

    /**
     * 为了防止屏幕旋转的情况,需要取出参数
     * 在 new 的时候去设置好参数
     * @param savedInstanceState state
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
        }
    }

    /**
     * 在这里初始化好View,获取到控件
     * @return View
     */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_blank, container, false);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }
    
    /**
     * 这个接口由Activity实现,就可以进行通信
     *      注意,是在 onAttach 和 onDetach 
     *      中注册监听和销毁监听
     */
    public interface OnFragmentInteractionListener {
        void onFragmentInteraction(Uri uri);
    }
}
复制代码

7. ViewPager中Fragment懒加载

Demo

  • setContentView:获取布局
  • initView:进行View控件的绑定
  • lazyLoad:懒加载
public abstract class LazyLoadFragment extends Fragment {

    protected View rootView;
    private boolean isInitView = false;
    private boolean isVisible = false;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        rootView = inflater.inflate(setContentView(), container, false);
        initView();
        isInitView = true;
        isCanLoadData();
        return rootView;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if(isVisibleToUser){
            isVisible = true;
            isCanLoadData();
        }else{
            isVisible = false;
        }
    }

    private void isCanLoadData(){
        if(isInitView && isVisible ){
            lazyLoad();
            isInitView = false;
            isVisible = false;
        }
    }

    protected abstract int setContentView();
    protected abstract void initView();
    protected abstract void lazyLoad();
}
复制代码

8. Fragment的生命周期

理解Fragment生命周期

浅谈Android中的 Fragment、生命周期回调方法 以及使用

Fragment的生命周期和Activity息息相关

onAttach():fragment已经关联到activity,getActivity不为空,与onDetach()对应

onCreate():系统创建fragment的时候回调他,在他里面实例化一些变量,这些个变量主要是:当你暂停、停止的时候,你想保持的数据,他只调用一次。

onCreateView():fragment加载布局

onActivityCreated():Activity中的onCreate方法执行完后调用。与activity有交互的UI操作,再onActivityCreated()中执行,确保Activity已经完成布局。

onStart():和Activity一致,启动Fragment

onResume():fragment可见,获取焦点

onPause():fragment暂停,其他activity获取焦点

onStop():和activity一致, fragment不可见的, 可能情况:activity被stopped了或者 fragment被移除但被,加入到回退栈中,一个stopped的fragment仍然是活着的如果长时间不用也会被移除。

onDestroyView():Fragment中的布局被移除时调用。表示fragemnt销毁相关联的UI布局, 清除所有跟视图相关的资源。然后这个只是识移除视图,并没有销毁而且还没有脱离activity

onDestroy():销毁fragment对象, 跟activity类似了。

onDetach(): Fragment和Activity解除关联的时候调用,脱离activity。

9. 嵌套Fragment

当在 Fragment 中要用到 FragmentManager 的时候一定要记住,使用 getChildFragmentManager()。

转载于:https://juejin.im/post/5c8f5729f265da611e176a4a

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值