ViewPager与recycleView同时使用时出现的View加载空白问题
来源:互联网 发布:mac常用软件推荐 2016 编辑:程序博客网 时间:2024/06/05 11:58
一.问题简述:
ViewPager一般常用于与Fragment结合或者与View结合使用,当布局只有ViewpPager时,View的加载十分的完美,当加入RecycleView时出现了问题,第一张和第二张View可以加载,但是第三张以后是空白View,这不是重点,重点是调试的时候,ViewPager的View的加载又是十分的完美,而运行的时候又会出现加载空白问题,真的是感觉醉醉的。。。
二.问题分析:
经过我的调试排除了以下可能(可能出现空白的原因):
①mImageView的问题:序号问题、越界问题、mImageView没获得数据问题(反正就是非常的确定不是mImageView的问题)
②adpater的问题:页面被覆盖问题:加载和释放图片时间不合理问题(反正就是非常的确定不是adapter的问题)
毕竟没加入RecycleView时一切正常,所以排除了上述可能原因。
1.Fragment的onCreateView()代码,模块ViewPager的adapter代码模块:
public class HomePageFragment extends Fragment { ... @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = LayoutInflater.from(getContext()).inflate(R.layout.home_page, container, false); ButterKnife.bind(this, view); init(); //ViewPager模块 pointInit(); mMyPagerAdapter = new MyPagerAdapter(mImageViews); mImagePager.setAdapter(mMyPagerAdapter); mMyThread.start();//这是开启线程每隔一段时间切花图片线程(不用关注) viewPagerChange();//ViewPager换页监听器(不用关注) //RecycleView列表 initRecycleViewList();//获取到RecycleView列表的数据(不用关注) mMyRecycleViewAdapter = new MyRecycleViewAdapter(getContext(),mLists); mRecycleView.setAdapter(mMyRecycleViewAdapter); LinearLayoutManager mLinearLayoutManager = new LinearLayoutManager(getContext(),LinearLayoutManager.VERTICAL,false); mRecycleView.setLayoutManager(mLinearLayoutManager); return view; } class MyPagerAdapter extends PagerAdapter{ private List<ImageView> mImageViews; public MyPagerAdapter(List<ImageView> mImageViews) { this.mImageViews = mImageViews; } @Override public int getCount() { return mImageViews.size(); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { mImageViews.get(position).setScaleType(ImageView.ScaleType.FIT_XY); container.addView(mImageViews.get(position)); return mImageViews.get(position); } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(mImageViews.get(position)); } }//其他代码... }
2.recycleView的adapter中的ViewHolder的绑定的代码。
@Overridepublic void onBindViewHolder(final MyViewHolder holder, final int position) { HttpUtil.sendHttpRequest(mList.get(position).getmTourismImageString(), new HttpCallbackListener() { @Override public void onFinish(byte[] picByte) { Bitmap bitmap = BitmapFactory.decodeByteArray(picByte, 0, picByte.length); bitmapList.add(bitmap); holder.mTourismImage.setImageBitmap(bitmap); } @Override public void onError(Exception e) { e.printStackTrace(); } }); holder.mTourismName.setText(mList.get(position).getmTourismNameString()); holder.mTravelDistance.setText(mList.get(position).getmTravelDistance()); holder.mDescribe.setText(mList.get(position).getmDescribe()); holder.mPrice.setText(mList.get(position).getmPrice()+""); holder.mRatingBar.setRating((float) mList.get(position).getmRatingBarProgress()); holder.mTicketsSold.setText(mList.get(position).getmTicketsSoldNum()+"");}
这是recycleView的adapter方法中的绑定ViewHolder方法的代码,大体是通过接口回调机制获取到网络图片的byte数组,再转化为bitmap从而给mTourismImage赋值。
大体说一说接口回调机制:主要是为了解决某些数据获取需要时间,当执行到此步时,使用接口回调机制当获取到数据是再去执行,从而解决未获取到数据时进行该操作。
3.回调接口HttpCallbackListener 与获取网络图片Http类(自定义的)的代码:
①回调接口HttpCallbackListener
public interface HttpCallbackListener { void onFinish(byte[] picByte); //获取到数据时执行该方法 void onError(Exception e); //未获取到数据时执行该方法}②获取网络图片Http类
public class HttpUtil { public static byte[] picByte; public static void sendHttpRequest(final String address,final HttpCallbackListener listener){ new Thread(new Runnable() { @Override public void run() { try { Log.d("TAG","请求运行了"); URL url = new URL(address); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setReadTimeout(10000); if(connection.getResponseCode() == 200) { InputStream is = connection.getInputStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] bytes = new byte[1024]; int length = -1; while((length = is.read(bytes)) != -1) { bos.write(bytes,0,length); } picByte = bos.toByteArray(); is.close(); bos.close(); if(listener != null) { listener.onFinish(picByte); } } } catch (Exception e) { if(listener != null) { listener.onError(e); } e.printStackTrace(); } } }).start(); }}运行时,网络图片的却加载出来了,然而viewPager加载View时第三张以后就出现了空白,本人当时感觉recyleView的实现与ViewPager的实现并没有影响呀,为什么会这样???
最后我发现ViewPager与RecycleView的关联只有一个,那就是他们合起来生成了Fragment(注意这里的Fragment所适配的ViewPager是另外一个,不需要与文中的ViewPager联系),给Fragment返回了一个View,也就是说网络图片生成时影响了这个View从而造成了空白的产生。
三.问题解决:
①原因分析:通过仔细的观察网络图片的加载过程发现,加载图片是在接口回调机制中实现的,而该接口的方法实现是在Http中开启了一个子线程实现的,说到这里就有人明白了,弄了半天原来是因为接口回调机制中存在子线程,当我们使用接口回调机制时不经意的在子线程中对UI进行了操作(自己以为是主线程!!),其实这点还真不容易发现,毕竟以接口做参数的Http.sendHttpRequest(final String address,final HttpCallbackListener listener)方法是在主线程中实现的,看起来就像是在主线程中对UI进行的操作。
② 解决方法:通过Handler发送信息,在Handler中对UI进行操作。源码如下:
public class MyRecycleViewAdapter extends RecyclerView.Adapter<MyViewHolder> { private MyViewHolder mMyViewHolder; private LayoutInflater mLayoutInflater; private Context mContext; private List<TouristInformation> mList; public static List<ImageView> mImageViewList; public static List<Bitmap> bitmapList; private MyHandler myHandler; public MyRecycleViewAdapter(Context context, List<TouristInformation> mList) { this.mContext = context; this.mList = mList; bitmapList = new ArrayList<>(); mImageViewList = new ArrayList<>(); myHandler = new MyHandler(); mLayoutInflater = LayoutInflater.from(context); } @Override public MyViewHolder onCreateViewHolder(ViewGroup ag0, int viewType) { View view = mLayoutInflater.inflate(R.layout.tourist_information, ag0, false); mMyViewHolder = new MyViewHolder(view); return mMyViewHolder; } @Override public void onBindViewHolder(final MyViewHolder holder, final int position) { HttpUtil.sendHttpRequest(mList.get(position).getmTourismImageString(), new HttpCallbackListener() { @Override public void onFinish(byte[] picByte) { Bitmap bitmap = BitmapFactory.decodeByteArray(picByte, 0, picByte.length); bitmapList.add(bitmap); myHandler.sendEmptyMessage(0x123); } @Override public void onError(Exception e) { e.printStackTrace(); } }); mImageViewList.add(holder.mTourismImage); holder.mTourismName.setText(mList.get(position).getmTourismNameString()); holder.mTravelDistance.setText(mList.get(position).getmTravelDistance()); holder.mDescribe.setText(mList.get(position).getmDescribe()); holder.mPrice.setText(mList.get(position).getmPrice()+""); holder.mRatingBar.setRating((float) mList.get(position).getmRatingBarProgress()); holder.mTicketsSold.setText(mList.get(position).getmTicketsSoldNum()+""); } @Override public int getItemCount() { return mList.size(); } class MyHandler extends Handler{ @Override public void handleMessage(Message msg) { if(msg.what == 0x123) { mImageViewList.get(0).setImageBitmap(bitmapList.get(0));//我这里只给第一个设置了bitmap } } }}class MyViewHolder extends RecyclerView.ViewHolder { @BindView(R.id.tourismImage) ImageView mTourismImage; @BindView(R.id.touristName) TextView mTourismName; @BindView(R.id.travelDistance) TextView mTravelDistance; @BindView(R.id.describe) TextView mDescribe; @BindView(R.id.price) TextView mPrice; @BindView(R.id.ratingBar) RatingBar mRatingBar; @BindView(R.id.ticketsSold) TextView mTicketsSold; public MyViewHolder(View view) { super(view); ButterKnife.bind(this, view); }}③总结:使用接口回调机制时最好通过Handler对UI进行操作,防止出现莫名其妙的bug。
- ViewPager与recycleView同时使用时出现的View加载空白问题
- 使用ViewPager加载页面出现空白--笔记
- 使用ViewPager加载页面出现空白
- 使用ViewPager设置适配器FragmentPagerAdapter出现页面空白的问题
- Viewpager+Fragment出现空白页面的问题
- Viewpager+Fragment出现空白页面的问题
- servlet与struts同时使用时出现的问题
- Recycleview嵌套Recycleview时出现的一个问题-待解决
- 解决Fragment中使用ViewPager时,ViewPager里的Fragment错位和空白问题
- 解决Fragment中使用ViewPager时,ViewPager里的Fragment错位和空白问题。
- 解决Fragment中使用ViewPager时,ViewPager里的Fragment错位和空白问题。
- (4.3.1.12)Fragment中使用ViewPager时,ViewPager里的Fragment错位和空白问题。
- recycleview+NestedScrollView+viewpager 解决滑动问题以及recycleview的使用技巧
- viewpager+fragment互相切换出现空白问题
- andorid GridView与scrollView同时使用出现的问题
- andorid GridView与scrollView同时使用出现的问题
- fragment+viewpager第二次加载页面时显示空白的原因!
- 使用Fragment+ViewPager中遇到的显示空白的问题
- 自定义的adpapter的getview方法多次执行
- c++ typedef用法小结
- 技术点总结(2016.08.01)
- Oracle SQL developer 输入字体异常
- DrawerLayout使用(实现SlidingMenuUI效果)
- ViewPager与recycleView同时使用时出现的View加载空白问题
- java中的移位操作
- 九度oj--开始
- Quick plot of all variables
- 设置Office 365移动设备管理MDM服务——创建设备安全策略
- SQL server 创建与删除数据库,数据表,约束的创建与删除语法
- 字符串的输出
- 使用libjpeg进行JPEG图像解码
- Solr之——solr5.2.1环境搭建