AndroidX中从Fragment向AdapterViewPager传入图片URL及空指针问题解决
解决Adapter空指针并实现Fragment向ViewPager适配器传入图片URL的问题
嘿,这个空指针问题其实很好定位——你完全搞反了代码的执行顺序!在调用adapterViewPagerHot.setUrls(strArray)的时候,adapterViewPagerHot还只是个null对象(你后面才去实例化它),这不报错才怪呢。
我给你整理了完整的修复方案,还加了几个优化点:
第一步:修正Fragment中代码的执行顺序
先初始化适配器实例,再调用setUrls方法,最后把适配器绑定到ViewPager上。修改后的TabHotFragment关键代码如下:
@Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { v = inflater.inflate(R.layout.fragment_tabhot, container, false); // 1. 先找到ViewPager和指示器控件 viewPager = (ViewPager) v.findViewById(R.id.viewPager); sliderDotspanel = (LinearLayout) v.findViewById(R.id.SliderDots); // 2. 初始化适配器实例 adapterViewPagerHot = new AdapterViewPagerHot(getActivity()); // 3. 传入自定义的图片URL数组 String[] strArray = new String[]{"https://scx1.b-cdn.net/csz/news/800/2019/1-nasastessmis.jpg"}; adapterViewPagerHot.setUrls(strArray); // 4. 绑定适配器到ViewPager viewPager.setAdapter(adapterViewPagerHot); // 其余代码... return v; }
第二步:优化适配器的setUrls方法并添加刷新逻辑
默认的PagerAdapter在数据源变化时不会自动刷新视图,所以我们要给适配器加两个关键修改:
- 在
setUrls里调用notifyDataSetChanged()通知视图更新 - 重写
getItemPosition方法,确保ViewPager会重新加载页面
修改后的AdapterViewPagerHot代码:
public class AdapterViewPagerHot extends PagerAdapter { private Context mContext; private LayoutInflater layoutInflater; public String image_url[] = new String[]{ "https://i.chzbgr.com/full/8803531264/hD42E57C6/" }; public AdapterViewPagerHot(Context context) { this.mContext = context; // 把LayoutInflater初始化移到构造函数,避免重复创建 layoutInflater = LayoutInflater.from(context); } @Override public int getCount() { return image_url.length; } public void setUrls(String[] list){ this.image_url = list; // 通知适配器数据源已更新 notifyDataSetChanged(); } // 重写此方法,确保数据源变化时ViewPager能刷新页面 @Override public int getItemPosition(Object object) { return POSITION_NONE; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, final int position) { // 更规范的布局加载方式,让布局继承ViewPager的LayoutParams View vi = layoutInflater.inflate(R.layout.item_viewpagerdisplay, container, false); ImageView imageView = vi.findViewById(R.id.imageView); final ImageView ICONHotViewPagerSaving = vi.findViewById(R.id.ICON_HotViewPagerSaving); Glide.with(mContext).load(image_url[position]).into(imageView); vi.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(mContext, "Slide" + (position+1) + "Clicked", Toast.LENGTH_SHORT).show(); } }); final Boolean[] boollatestnewssaving = {false}; ICONHotViewPagerSaving.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 简化布尔判断写法 if (boollatestnewssaving[0]){ Toast.makeText(v.getContext(), "Turn Off Saved News ", Toast.LENGTH_SHORT).show(); ICONHotViewPagerSaving.setImageResource(R.drawable.saved_off); boollatestnewssaving[0] = false; } else { Toast.makeText(v.getContext(), "Turn On Saved News ", Toast.LENGTH_SHORT).show(); ICONHotViewPagerSaving.setImageResource(R.drawable.saved_on); boollatestnewssaving[0] = true; } } }); container.addView(vi); return vi; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } }
额外的小优化说明
- 把
LayoutInflater的初始化移到构造函数,避免每次创建页面都重复获取系统服务 - 布局加载时使用
container作为父容器,让页面布局能正确继承ViewPager的布局参数 - 简化了布尔判断的写法,让代码更简洁
- 去掉了多余的
sContext变量,直接使用成员变量mContext即可
内容的提问来源于stack exchange,提问作者Antony Sunggaki
相关产品推荐
相关产品推荐

